⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 zipup.c

📁 给出了 zip 压缩算法的完整实现过程。
💻 C
📖 第 1 页 / 共 3 页
字号:
          if ((c = *b++) == '\r' && *b == '\n') {             len--;          } else {             *buf++ = (char)(c == '\n' ? LF : ascii[(uch)c]);          }       } while (--size != 0);    }    else#endif /* EBCDIC */    {       do {          if (( *buf++ = *b++) == CR && *b == LF) buf--, len--;       } while (--size != 0);    }    if (len == 0) {       zread(ifile, buf, 1); len = 1; /* keep single \r if EOF */#ifdef EBCDIC       if (aflag == ASCII) {          *buf = (char)(*buf == '\n' ? LF : ascii[(uch)(*buf)]);       }#endif    } else {       buf -= len;       if (buf[len-1] == CTRLZ) len--; /* suppress final ^Z */    }  }  crc = crc32(crc, (uch *) buf, len);  isize += (ulg)len;  /* added check for file size - 2/20/05 */  if ((isize & (ulg)0xffffffffL) < (ulg)len) {    /* fatal error: file size exceeds Zip limit */    ZIPERR(ZE_BIG, "file exceeds Zip's 4GB uncompressed size limit");  }  return len;}#ifdef USE_ZLIBlocal int zl_deflate_init(pack_level)    int pack_level;{    unsigned i;    int windowBits;    int err = Z_OK;    int zp_err = ZE_OK;    if (zlib_version[0] != ZLIB_VERSION[0]) {        sprintf(errbuf, "incompatible zlib version (expected %s, found %s)",              ZLIB_VERSION, zlib_version);        zp_err = ZE_LOGIC;    } else if (strcmp(zlib_version, ZLIB_VERSION) != 0) {        fprintf(stderr,                "\twarning:  different zlib version (expected %s, using %s)\n",                ZLIB_VERSION, zlib_version);    }    /* windowBits = log2(WSIZE) */    for (i = ((unsigned)WSIZE), windowBits = 0; i != 1; i >>= 1, ++windowBits);    zstrm.zalloc = (alloc_func)Z_NULL;    zstrm.zfree = (free_func)Z_NULL;    Trace((stderr, "initializing deflate()\n"));    err = deflateInit2(&zstrm, pack_level, Z_DEFLATED, -windowBits, 8, 0);    if (err == Z_MEM_ERROR) {        sprintf(errbuf, "cannot initialize zlib deflate");        zp_err = ZE_MEM;    } else if (err != Z_OK) {        sprintf(errbuf, "zlib deflateInit failure (%d)", err);        zp_err = ZE_LOGIC;    }    deflInit = TRUE;    return zp_err;}void zl_deflate_free(){    int err;    if (f_obuf != NULL) {        free(f_obuf);        f_obuf = NULL;    }    if (f_ibuf != NULL) {        free(f_ibuf);        f_ibuf = NULL;    }    if (deflInit) {        err = deflateEnd(&zstrm);        if (err != Z_OK && err !=Z_DATA_ERROR) {            ziperr(ZE_LOGIC, "zlib deflateEnd failed");        }    }}#else /* !USE_ZLIB */#ifdef ZP_NEED_MEMCOMPR/* =========================================================================== * In-memory read function. As opposed to file_read(), this function * does not perform end-of-line translation, and does not update the * crc and input size. *    Note that the size of the entire input buffer is an unsigned long, * but the size used in mem_read() is only an unsigned int. This makes a * difference on 16 bit machines. mem_read() may be called several * times for an in-memory compression. */local unsigned mem_read(b, bsize)     char *b;     unsigned bsize;{    if (in_offset < in_size) {        ulg block_size = in_size - in_offset;        if (block_size > (ulg)bsize) block_size = (ulg)bsize;        memcpy(b, in_buf + in_offset, (unsigned)block_size);        in_offset += (unsigned)block_size;        return (unsigned)block_size;    } else {        return 0; /* end of input */    }}#endif /* ZP_NEED_MEMCOMPR *//* =========================================================================== * Flush the current output buffer. */void flush_outbuf(o_buf, o_idx)    char *o_buf;    unsigned *o_idx;{    if (zfile == NULL) {        error("output buffer too small for in-memory compression");    }    /* Encrypt and write the output buffer: */    if (*o_idx != 0) {        zfwrite(o_buf, 1, (extent)*o_idx, zfile);        if (ferror(zfile)) ziperr(ZE_WRITE, "write error on zip file");    }    *o_idx = 0;}/* =========================================================================== * Return true if the zip file can be seeked. This is used to check if * the local header can be re-rewritten. This function always returns * true for in-memory compression. * IN assertion: the local header has already been written (ftell() > 0). */int seekable(){    return fseekable(zfile);}#endif /* ?USE_ZLIB *//* =========================================================================== * Compression to archive file. */local ulg filecompress(z_entry, zipfile, cmpr_method)    struct zlist far *z_entry;    FILE *zipfile;    int *cmpr_method;{#ifdef USE_ZLIB    int err = Z_OK;    unsigned mrk_cnt = 1;    int maybe_stored = FALSE;    ulg cmpr_size;#if defined(MMAP) || defined(BIG_MEM)    unsigned ibuf_sz = (unsigned)SBSZ;#else#   define ibuf_sz ((unsigned)SBSZ)#endif#ifndef OBUF_SZ#  define OBUF_SZ ZBSZ#endif#if defined(MMAP) || defined(BIG_MEM)    if (remain == (ulg)-1L && f_ibuf == NULL)#else /* !(MMAP || BIG_MEM */    if (f_ibuf == NULL)#endif /* MMAP || BIG_MEM */        f_ibuf = (char *)malloc(SBSZ);    if (f_obuf == NULL)        f_obuf = (char *)malloc(OBUF_SZ);#if defined(MMAP) || defined(BIG_MEM)    if ((remain == (ulg)-1L && f_ibuf == NULL) || f_obuf == NULL)#else /* !(MMAP || BIG_MEM */    if (f_ibuf == NULL || f_obuf == NULL)#endif /* MMAP || BIG_MEM */        ziperr(ZE_MEM, "allocating zlib file-I/O buffers");    if (!deflInit) {        err = zl_deflate_init(level);        if (err != ZE_OK)            ziperr(err, errbuf);    }    if (level <= 2) {        z_entry->flg |= 4;    } else if (level >= 8) {        z_entry->flg |= 2;    }#if defined(MMAP) || defined(BIG_MEM)    if (remain != (ulg)-1L) {        zstrm.next_in = (Bytef *)window;        ibuf_sz = (unsigned)WSIZE;    } else#endif /* MMAP || BIG_MEM */    {        zstrm.next_in = (Bytef *)f_ibuf;    }    zstrm.avail_in = file_read(zstrm.next_in, ibuf_sz);    if (zstrm.avail_in < ibuf_sz) {        unsigned more = file_read(zstrm.next_in + zstrm.avail_in,                                  (ibuf_sz - zstrm.avail_in));        if (more == EOF || more == 0) {            maybe_stored = TRUE;        } else {            zstrm.avail_in += more;        }    }    zstrm.next_out = (Bytef *)f_obuf;    zstrm.avail_out = OBUF_SZ;    if (!maybe_stored) while (zstrm.avail_in != 0 && zstrm.avail_in != EOF) {        err = deflate(&zstrm, Z_NO_FLUSH);        if (err != Z_OK && err != Z_STREAM_END) {            sprintf(errbuf, "unexpected zlib deflate error %d", err);            ziperr(ZE_LOGIC, errbuf);        }        if (zstrm.avail_out == 0) {            if (zfwrite(f_obuf, 1, OBUF_SZ, zipfile) != OBUF_SZ) {                ziperr(ZE_TEMP, "error writing to zipfile");            }            zstrm.next_out = (Bytef *)f_obuf;            zstrm.avail_out = OBUF_SZ;        }        if (zstrm.avail_in == 0) {            if (verbose)                while((unsigned)(zstrm.total_in / (uLong)WSIZE) > mrk_cnt) {                    mrk_cnt++;#ifndef WINDLL                    putc('.', stderr);                    fflush(stderr);#else                    fprintf(stdout,"%c",'.');#endif                }#if defined(MMAP) || defined(BIG_MEM)            if (remain == (ulg)-1L)                zstrm.next_in = (Bytef *)f_ibuf;#else            zstrm.next_in = (Bytef *)f_ibuf;#endif            zstrm.avail_in = file_read(zstrm.next_in, ibuf_sz);        }    }    do {        err = deflate(&zstrm, Z_FINISH);        if (maybe_stored) {            if (err == Z_STREAM_END && zstrm.total_out >= zstrm.total_in &&                fseekable(zipfile)) {                /* deflation does not reduce size, switch to STORE method */                unsigned len_out = (unsigned)zstrm.total_in;                if (zfwrite(f_ibuf, 1, len_out, zipfile) != len_out) {                    ziperr(ZE_TEMP, "error writing to zipfile");                }                zstrm.total_out = (uLong)len_out;                *cmpr_method = STORE;                break;            } else {                maybe_stored = FALSE;            }        }        if (zstrm.avail_out < OBUF_SZ) {            unsigned len_out = OBUF_SZ - zstrm.avail_out;            if (zfwrite(f_obuf, 1, len_out, zipfile) != len_out) {                ziperr(ZE_TEMP, "error writing to zipfile");            }            zstrm.next_out = (Bytef *)f_obuf;            zstrm.avail_out = OBUF_SZ;        }    } while (err == Z_OK);    if (err != Z_STREAM_END) {        sprintf(errbuf, "unexpected zlib deflate error %d", err);        ziperr(ZE_LOGIC, errbuf);    }    if (z_entry->att == (ush)UNKNOWN)        z_entry->att = (ush)(zstrm.data_type == Z_ASCII ? ASCII : BINARY);    cmpr_size = (ulg)zstrm.total_out;    if ((err = deflateReset(&zstrm)) != Z_OK)        ziperr(ZE_LOGIC, "zlib deflateReset failed");    return cmpr_size;#else /* !USE_ZLIB */    /* Set the defaults for file compression. */    zfile = zipfile;    read_buf = file_read;    /* Initialize deflate's internals and execute file compression. */    bi_init(file_outbuf, sizeof(file_outbuf), TRUE);    ct_init(&z_entry->att, cmpr_method);    lm_init(level, &z_entry->flg);    return deflate();#endif /* ?USE_ZLIB */}#ifdef ZP_NEED_MEMCOMPR/* =========================================================================== * In-memory compression. This version can be used only if the entire input * fits in one memory buffer. The compression is then done in a single * call of memcompress(). (An extension to allow repeated calls would be * possible but is not needed here.) * The first two bytes of the compressed output are set to a short with the * method used (DEFLATE or STORE). The following four bytes contain the CRC. * The values are stored in little-endian order on all machines. * This function returns the byte size of the compressed output, including * the first six bytes (method and crc). */ulg memcompress(tgt, tgtsize, src, srcsize)    char *tgt, *src;       /* target and source buffers */    ulg tgtsize, srcsize;  /* target and source sizes */{    ulg crc;    unsigned out_total;    int method   = DEFLATE;#ifdef USE_ZLIB    int err      = Z_OK;#else    ush att      = (ush)UNKNOWN;    ush flags    = 0;#endif    if (tgtsize <= (ulg)6L) error("target buffer too small");    out_total = 2 + 4;#ifdef USE_ZLIB    if (!deflInit) {        err = zl_deflate_init(level);        if (err != ZE_OK)            ziperr(err, errbuf);    }    zstrm.next_in = (Bytef *)src;    zstrm.avail_in = (uInt)srcsize;    zstrm.next_out = (Bytef *)(tgt + out_total);    zstrm.avail_out = (uInt)tgtsize - (uInt)out_total;    err = deflate(&zstrm, Z_FINISH);    if (err != Z_STREAM_END)        error("output buffer too small for in-memory compression");    out_total += (unsigned)zstrm.total_out;    if ((err = deflateReset(&zstrm)) != Z_OK)        error("zlib deflateReset failed");#else /* !USE_ZLIB */    zfile     = NULL;    read_buf  = mem_read;    in_buf    = src;    in_size   = (unsigned)srcsize;    in_offset = 0;    window_size = 0L;    bi_init(tgt + (2 + 4), (unsigned)(tgtsize - (2 + 4)), FALSE);    ct_init(&att, &method);    lm_init((level != 0 ? level : 1), &flags);    out_total += (unsigned)deflate();    window_size = 0L; /* was updated by lm_init() */#endif /* ?USE_ZLIB */    crc = CRCVAL_INITIAL;    crc = crc32(crc, (uch *)src, (extent)srcsize);    /* For portability, force little-endian order on all machines: */    tgt[0] = (char)(method & 0xff);    tgt[1] = (char)((method >> 8) & 0xff);    tgt[2] = (char)(crc & 0xff);    tgt[3] = (char)((crc >> 8) & 0xff);    tgt[4] = (char)((crc >> 16) & 0xff);    tgt[5] = (char)((crc >> 24) & 0xff);    return (ulg)out_total;}#endif /* ZP_NEED_MEMCOMPR */#endif /* !UTIL */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -