ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

gzwrite.c
Go to the documentation of this file.
00001 /* gzwrite.c -- zlib functions for writing gzip files
00002  * Copyright (C) 2004, 2005, 2010 Mark Adler
00003  * For conditions of distribution and use, see copyright notice in zlib.h
00004  */
00005 
00006 #include "gzguts.h"
00007 
00008 /* Local functions */
00009 local int gz_init OF((gz_statep));
00010 local int gz_comp OF((gz_statep, int));
00011 local int gz_zero OF((gz_statep, z_off64_t));
00012 
00013 /* Initialize state for writing a gzip file.  Mark initialization by setting
00014    state->size to non-zero.  Return -1 on failure or 0 on success. */
00015 local int gz_init(state)
00016     gz_statep state;
00017 {
00018     int ret;
00019     z_streamp strm = &(state->strm);
00020 
00021     /* allocate input and output buffers */
00022     state->in = malloc(state->want);
00023     state->out = malloc(state->want);
00024     if (state->in == NULL || state->out == NULL) {
00025         if (state->out != NULL)
00026             free(state->out);
00027         if (state->in != NULL)
00028             free(state->in);
00029         gz_error(state, Z_MEM_ERROR, "out of memory");
00030         return -1;
00031     }
00032 
00033     /* allocate deflate memory, set up for gzip compression */
00034     strm->zalloc = Z_NULL;
00035     strm->zfree = Z_NULL;
00036     strm->opaque = Z_NULL;
00037     ret = deflateInit2(strm, state->level, Z_DEFLATED,
00038                        15 + 16, 8, state->strategy);
00039     if (ret != Z_OK) {
00040         free(state->in);
00041         gz_error(state, Z_MEM_ERROR, "out of memory");
00042         return -1;
00043     }
00044 
00045     /* mark state as initialized */
00046     state->size = state->want;
00047 
00048     /* initialize write buffer */
00049     strm->avail_out = state->size;
00050     strm->next_out = state->out;
00051     state->next = strm->next_out;
00052     return 0;
00053 }
00054 
00055 /* Compress whatever is at avail_in and next_in and write to the output file.
00056    Return -1 if there is an error writing to the output file, otherwise 0.
00057    flush is assumed to be a valid deflate() flush value.  If flush is Z_FINISH,
00058    then the deflate() state is reset to start a new gzip stream. */
00059 local int gz_comp(state, flush)
00060     gz_statep state;
00061     int flush;
00062 {
00063     int ret, got;
00064     unsigned have;
00065     z_streamp strm = &(state->strm);
00066 
00067     /* allocate memory if this is the first time through */
00068     if (state->size == 0 && gz_init(state) == -1)
00069         return -1;
00070 
00071     /* run deflate() on provided input until it produces no more output */
00072     ret = Z_OK;
00073     do {
00074         /* write out current buffer contents if full, or if flushing, but if
00075            doing Z_FINISH then don't write until we get to Z_STREAM_END */
00076         if (strm->avail_out == 0 || (flush != Z_NO_FLUSH &&
00077             (flush != Z_FINISH || ret == Z_STREAM_END))) {
00078             have = (unsigned)(strm->next_out - state->next);
00079             if (have && ((got = write(state->fd, state->next, have)) < 0 ||
00080                          (unsigned)got != have)) {
00081                 gz_error(state, Z_ERRNO, zstrerror());
00082                 return -1;
00083             }
00084             if (strm->avail_out == 0) {
00085                 strm->avail_out = state->size;
00086                 strm->next_out = state->out;
00087             }
00088             state->next = strm->next_out;
00089         }
00090 
00091         /* compress */
00092         have = strm->avail_out;
00093         ret = deflate(strm, flush);
00094         if (ret == Z_STREAM_ERROR) {
00095             gz_error(state, Z_STREAM_ERROR,
00096                       "internal error: deflate stream corrupt");
00097             return -1;
00098         }
00099         have -= strm->avail_out;
00100     } while (have);
00101 
00102     /* if that completed a deflate stream, allow another to start */
00103     if (flush == Z_FINISH)
00104         deflateReset(strm);
00105 
00106     /* all done, no errors */
00107     return 0;
00108 }
00109 
00110 /* Compress len zeros to output.  Return -1 on error, 0 on success. */
00111 local int gz_zero(state, len)
00112     gz_statep state;
00113     z_off64_t len;
00114 {
00115     int first;
00116     unsigned n;
00117     z_streamp strm = &(state->strm);
00118 
00119     /* consume whatever's left in the input buffer */
00120     if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1)
00121         return -1;
00122 
00123     /* compress len zeros (len guaranteed > 0) */
00124     first = 1;
00125     while (len) {
00126         n = GT_OFF(state->size) || (z_off64_t)state->size > len ?
00127             (unsigned)len : state->size;
00128         if (first) {
00129             memset(state->in, 0, n);
00130             first = 0;
00131         }
00132         strm->avail_in = n;
00133         strm->next_in = state->in;
00134         state->pos += n;
00135         if (gz_comp(state, Z_NO_FLUSH) == -1)
00136             return -1;
00137         len -= n;
00138     }
00139     return 0;
00140 }
00141 
00142 /* -- see zlib.h -- */
00143 int ZEXPORT gzwrite(file, buf, len)
00144     gzFile file;
00145     voidpc buf;
00146     unsigned len;
00147 {
00148     unsigned put = len;
00149     unsigned n;
00150     gz_statep state;
00151     z_streamp strm;
00152 
00153     /* get internal structure */
00154     if (file == NULL)
00155         return 0;
00156     state = (gz_statep)file;
00157     strm = &(state->strm);
00158 
00159     /* check that we're writing and that there's no error */
00160     if (state->mode != GZ_WRITE || state->err != Z_OK)
00161         return 0;
00162 
00163     /* since an int is returned, make sure len fits in one, otherwise return
00164        with an error (this avoids the flaw in the interface) */
00165     if ((int)len < 0) {
00166         gz_error(state, Z_BUF_ERROR, "requested length does not fit in int");
00167         return 0;
00168     }
00169 
00170     /* if len is zero, avoid unnecessary operations */
00171     if (len == 0)
00172         return 0;
00173 
00174     /* allocate memory if this is the first time through */
00175     if (state->size == 0 && gz_init(state) == -1)
00176         return 0;
00177 
00178     /* check for seek request */
00179     if (state->seek) {
00180         state->seek = 0;
00181         if (gz_zero(state, state->skip) == -1)
00182             return 0;
00183     }
00184 
00185     /* for small len, copy to input buffer, otherwise compress directly */
00186     if (len < state->size) {
00187         /* copy to input buffer, compress when full */
00188         do {
00189             if (strm->avail_in == 0)
00190                 strm->next_in = state->in;
00191             n = state->size - strm->avail_in;
00192             if (n > len)
00193                 n = len;
00194             memcpy(strm->next_in + strm->avail_in, buf, n);
00195             strm->avail_in += n;
00196             state->pos += n;
00197             buf = (char *)buf + n;
00198             len -= n;
00199             if (len && gz_comp(state, Z_NO_FLUSH) == -1)
00200                 return 0;
00201         } while (len);
00202     }
00203     else {
00204         /* consume whatever's left in the input buffer */
00205         if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1)
00206             return 0;
00207 
00208         /* directly compress user buffer to file */
00209         strm->avail_in = len;
00210         strm->next_in = (voidp)buf;
00211         state->pos += len;
00212         if (gz_comp(state, Z_NO_FLUSH) == -1)
00213             return 0;
00214     }
00215 
00216     /* input was all buffered or compressed (put will fit in int) */
00217     return (int)put;
00218 }
00219 
00220 /* -- see zlib.h -- */
00221 int ZEXPORT gzputc(file, c)
00222     gzFile file;
00223     int c;
00224 {
00225     unsigned char buf[1];
00226     gz_statep state;
00227     z_streamp strm;
00228 
00229     /* get internal structure */
00230     if (file == NULL)
00231         return -1;
00232     state = (gz_statep)file;
00233     strm = &(state->strm);
00234 
00235     /* check that we're writing and that there's no error */
00236     if (state->mode != GZ_WRITE || state->err != Z_OK)
00237         return -1;
00238 
00239     /* check for seek request */
00240     if (state->seek) {
00241         state->seek = 0;
00242         if (gz_zero(state, state->skip) == -1)
00243             return -1;
00244     }
00245 
00246     /* try writing to input buffer for speed (state->size == 0 if buffer not
00247        initialized) */
00248     if (strm->avail_in < state->size) {
00249         if (strm->avail_in == 0)
00250             strm->next_in = state->in;
00251         strm->next_in[strm->avail_in++] = c;
00252         state->pos++;
00253         return c;
00254     }
00255 
00256     /* no room in buffer or not initialized, use gz_write() */
00257     buf[0] = c;
00258     if (gzwrite(file, buf, 1) != 1)
00259         return -1;
00260     return c;
00261 }
00262 
00263 /* -- see zlib.h -- */
00264 int ZEXPORT gzputs(file, str)
00265     gzFile file;
00266     const char *str;
00267 {
00268     int ret;
00269     unsigned len;
00270 
00271     /* write string */
00272     len = (unsigned)strlen(str);
00273     ret = gzwrite(file, str, len);
00274     return ret == 0 && len != 0 ? -1 : ret;
00275 }
00276 
00277 #ifdef STDC
00278 #include <stdarg.h>
00279 
00280 /* -- see zlib.h -- */
00281 int ZEXPORTVA gzprintf (gzFile file, const char *format, ...)
00282 {
00283     int size, len;
00284     gz_statep state;
00285     z_streamp strm;
00286     va_list va;
00287 
00288     /* get internal structure */
00289     if (file == NULL)
00290         return -1;
00291     state = (gz_statep)file;
00292     strm = &(state->strm);
00293 
00294     /* check that we're writing and that there's no error */
00295     if (state->mode != GZ_WRITE || state->err != Z_OK)
00296         return 0;
00297 
00298     /* make sure we have some buffer space */
00299     if (state->size == 0 && gz_init(state) == -1)
00300         return 0;
00301 
00302     /* check for seek request */
00303     if (state->seek) {
00304         state->seek = 0;
00305         if (gz_zero(state, state->skip) == -1)
00306             return 0;
00307     }
00308 
00309     /* consume whatever's left in the input buffer */
00310     if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1)
00311         return 0;
00312 
00313     /* do the printf() into the input buffer, put length in len */
00314     size = (int)(state->size);
00315     state->in[size - 1] = 0;
00316     va_start(va, format);
00317 #ifdef NO_vsnprintf
00318 #  ifdef HAS_vsprintf_void
00319     (void)vsprintf(state->in, format, va);
00320     va_end(va);
00321     for (len = 0; len < size; len++)
00322         if (state->in[len] == 0) break;
00323 #  else
00324     len = vsprintf(state->in, format, va);
00325     va_end(va);
00326 #  endif
00327 #else
00328 #  ifdef HAS_vsnprintf_void
00329     (void)vsnprintf(state->in, size, format, va);
00330     va_end(va);
00331     len = strlen(state->in);
00332 #  else
00333     len = vsnprintf((char *)(state->in), size, format, va);
00334     va_end(va);
00335 #  endif
00336 #endif
00337 
00338     /* check that printf() results fit in buffer */
00339     if (len <= 0 || len >= (int)size || state->in[size - 1] != 0)
00340         return 0;
00341 
00342     /* update buffer and position, defer compression until needed */
00343     strm->avail_in = (unsigned)len;
00344     strm->next_in = state->in;
00345     state->pos += len;
00346     return len;
00347 }
00348 
00349 #else /* !STDC */
00350 
00351 /* -- see zlib.h -- */
00352 int ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
00353                        a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
00354     gzFile file;
00355     const char *format;
00356     int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
00357         a11, a12, a13, a14, a15, a16, a17, a18, a19, a20;
00358 {
00359     int size, len;
00360     gz_statep state;
00361     z_streamp strm;
00362 
00363     /* get internal structure */
00364     if (file == NULL)
00365         return -1;
00366     state = (gz_statep)file;
00367     strm = &(state->strm);
00368 
00369     /* check that we're writing and that there's no error */
00370     if (state->mode != GZ_WRITE || state->err != Z_OK)
00371         return 0;
00372 
00373     /* make sure we have some buffer space */
00374     if (state->size == 0 && gz_init(state) == -1)
00375         return 0;
00376 
00377     /* check for seek request */
00378     if (state->seek) {
00379         state->seek = 0;
00380         if (gz_zero(state, state->skip) == -1)
00381             return 0;
00382     }
00383 
00384     /* consume whatever's left in the input buffer */
00385     if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1)
00386         return 0;
00387 
00388     /* do the printf() into the input buffer, put length in len */
00389     size = (int)(state->size);
00390     state->in[size - 1] = 0;
00391 #ifdef NO_snprintf
00392 #  ifdef HAS_sprintf_void
00393     sprintf(state->in, format, a1, a2, a3, a4, a5, a6, a7, a8,
00394             a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
00395     for (len = 0; len < size; len++)
00396         if (state->in[len] == 0) break;
00397 #  else
00398     len = sprintf(state->in, format, a1, a2, a3, a4, a5, a6, a7, a8,
00399                 a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
00400 #  endif
00401 #else
00402 #  ifdef HAS_snprintf_void
00403     snprintf(state->in, size, format, a1, a2, a3, a4, a5, a6, a7, a8,
00404              a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
00405     len = strlen(state->in);
00406 #  else
00407     len = snprintf(state->in, size, format, a1, a2, a3, a4, a5, a6, a7, a8,
00408                  a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
00409 #  endif
00410 #endif
00411 
00412     /* check that printf() results fit in buffer */
00413     if (len <= 0 || len >= (int)size || state->in[size - 1] != 0)
00414         return 0;
00415 
00416     /* update buffer and position, defer compression until needed */
00417     strm->avail_in = (unsigned)len;
00418     strm->next_in = state->in;
00419     state->pos += len;
00420     return len;
00421 }
00422 
00423 #endif
00424 
00425 /* -- see zlib.h -- */
00426 int ZEXPORT gzflush(file, flush)
00427     gzFile file;
00428     int flush;
00429 {
00430     gz_statep state;
00431 
00432     /* get internal structure */
00433     if (file == NULL)
00434         return -1;
00435     state = (gz_statep)file;
00436 
00437     /* check that we're writing and that there's no error */
00438     if (state->mode != GZ_WRITE || state->err != Z_OK)
00439         return Z_STREAM_ERROR;
00440 
00441     /* check flush parameter */
00442     if (flush < 0 || flush > Z_FINISH)
00443         return Z_STREAM_ERROR;
00444 
00445     /* check for seek request */
00446     if (state->seek) {
00447         state->seek = 0;
00448         if (gz_zero(state, state->skip) == -1)
00449             return -1;
00450     }
00451 
00452     /* compress remaining data with requested flush */
00453     gz_comp(state, flush);
00454     return state->err;
00455 }
00456 
00457 /* -- see zlib.h -- */
00458 int ZEXPORT gzsetparams(file, level, strategy)
00459     gzFile file;
00460     int level;
00461     int strategy;
00462 {
00463     gz_statep state;
00464     z_streamp strm;
00465 
00466     /* get internal structure */
00467     if (file == NULL)
00468         return Z_STREAM_ERROR;
00469     state = (gz_statep)file;
00470     strm = &(state->strm);
00471 
00472     /* check that we're writing and that there's no error */
00473     if (state->mode != GZ_WRITE || state->err != Z_OK)
00474         return Z_STREAM_ERROR;
00475 
00476     /* if no change is requested, then do nothing */
00477     if (level == state->level && strategy == state->strategy)
00478         return Z_OK;
00479 
00480     /* check for seek request */
00481     if (state->seek) {
00482         state->seek = 0;
00483         if (gz_zero(state, state->skip) == -1)
00484             return -1;
00485     }
00486 
00487     /* change compression parameters for subsequent input */
00488     if (state->size) {
00489         /* flush previous input with previous parameters before changing */
00490         if (strm->avail_in && gz_comp(state, Z_PARTIAL_FLUSH) == -1)
00491             return state->err;
00492         deflateParams(strm, level, strategy);
00493     }
00494     state->level = level;
00495     state->strategy = strategy;
00496     return Z_OK;
00497 }
00498 
00499 /* -- see zlib.h -- */
00500 int ZEXPORT gzclose_w(file)
00501     gzFile file;
00502 {
00503     int ret = 0;
00504     gz_statep state;
00505 
00506     /* get internal structure */
00507     if (file == NULL)
00508         return Z_STREAM_ERROR;
00509     state = (gz_statep)file;
00510 
00511     /* check that we're writing */
00512     if (state->mode != GZ_WRITE)
00513         return Z_STREAM_ERROR;
00514 
00515     /* check for seek request */
00516     if (state->seek) {
00517         state->seek = 0;
00518         ret += gz_zero(state, state->skip);
00519     }
00520 
00521     /* flush, free memory, and close file */
00522     ret += gz_comp(state, Z_FINISH);
00523     (void)deflateEnd(&(state->strm));
00524     free(state->out);
00525     free(state->in);
00526     gz_error(state, Z_OK, NULL);
00527     free(state->path);
00528     ret += close(state->fd);
00529     free(state);
00530     return ret ? Z_ERRNO : Z_OK;
00531 }

Generated on Sun May 27 2012 04:35:55 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.