[BACK]Return to compress.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / cvs

Annotation of src/usr.bin/cvs/compress.c, Revision 1.5

1.5     ! pat         1: /*     $OpenBSD: compress.c,v 1.4 2006/04/14 02:45:35 deraadt Exp $    */
1.1       xsa         2: /*
1.5     ! pat         3:  * Copyright (c) 2006 Patrick Latifi <pat@openbsd.org>
1.1       xsa         4:  * Copyright (c) 2005 Jean-Francois Brousseau <jfb@openbsd.org>
                      5:  * All rights reserved.
                      6:  *
                      7:  * Redistribution and use in source and binary forms, with or without
                      8:  * modification, are permitted provided that the following conditions
                      9:  * are met:
                     10:  *
                     11:  * 1. Redistributions of source code must retain the above copyright
                     12:  *    notice, this list of conditions and the following disclaimer.
                     13:  * 2. The name of the author may not be used to endorse or promote products
                     14:  *    derived from this software without specific prior written permission.
                     15:  *
                     16:  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
                     17:  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
                     18:  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
                     19:  * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
                     20:  * EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLUDING, BUT NOT LIMITED TO,
                     21:  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
                     22:  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
                     23:  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
                     24:  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
                     25:  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
                     26:  */
                     27:
                     28: #include "includes.h"
                     29:
                     30: #include "log.h"
                     31: #include "cvs.h"
                     32: #include "compress.h"
                     33:
                     34: #define CVS_ZLIB_BUFSIZE       1024
                     35:
                     36: struct cvs_zlib_ctx {
                     37:        int             z_level;
                     38:        z_stream        z_instrm;
                     39:        z_stream        z_destrm;
                     40: };
                     41:
1.5     ! pat        42: struct zlib_ioctx {
        !            43:        z_stream *stream;
        !            44:        int     (*reset)(z_stream *);
        !            45:        int     (*io)(z_stream *, int);
        !            46:        int     ioflags;
        !            47: };
        !            48:
        !            49: static int cvs_zlib_io(struct zlib_ioctx *, BUF *, u_char *, size_t);
1.1       xsa        50:
                     51: /*
                     52:  * cvs_zlib_newctx()
                     53:  *
                     54:  * Allocate a new ZLIB context structure used for both inflation and deflation
                     55:  * of data with compression level <level>, which must be between 0 and 9.  A
                     56:  * value of 0 means no compression, and 9 is the highest level of compression.
                     57:  */
                     58: CVSZCTX *
                     59: cvs_zlib_newctx(int level)
                     60: {
                     61:        CVSZCTX *ctx;
                     62:
1.4       deraadt    63:        if (level < 0 || level > 9)
1.1       xsa        64:                fatal("invalid compression level %d (must be between 0 and 9)",
                     65:                    level);
                     66:
1.2       ray        67:        ctx = xcalloc(1, sizeof(*ctx));
1.1       xsa        68:
                     69:        ctx->z_level = level;
                     70:
                     71:        ctx->z_instrm.zalloc = Z_NULL;
                     72:        ctx->z_instrm.zfree = Z_NULL;
                     73:        ctx->z_instrm.opaque = Z_NULL;
                     74:        ctx->z_destrm.zalloc = Z_NULL;
                     75:        ctx->z_destrm.zfree = Z_NULL;
                     76:        ctx->z_destrm.opaque = Z_NULL;
                     77:
1.4       deraadt    78:        if (inflateInit(&(ctx->z_instrm)) != Z_OK ||
                     79:            deflateInit(&(ctx->z_destrm), level) != Z_OK)
1.1       xsa        80:                fatal("failed to initialize zlib streams");
                     81:
                     82:        return (ctx);
                     83: }
                     84:
                     85:
                     86: /*
                     87:  * cvs_zlib_free()
                     88:  *
                     89:  * Free a ZLIB context previously allocated with cvs_zlib_newctx().
                     90:  */
                     91: void
                     92: cvs_zlib_free(CVSZCTX *ctx)
                     93: {
                     94:        if (ctx != NULL) {
                     95:                (void)inflateEnd(&(ctx->z_instrm));
                     96:                (void)deflateEnd(&(ctx->z_destrm));
                     97:                xfree(ctx);
                     98:        }
                     99: }
                    100:
                    101: /*
                    102:  * cvs_zlib_inflate()
                    103:  *
                    104:  * Decompress the first <slen> bytes of <src> using the zlib context <ctx> and
                    105:  * store the resulting data in <dst>.
                    106:  * Returns the number of bytes inflated on success, or -1 on failure.
                    107:  */
                    108: int
                    109: cvs_zlib_inflate(CVSZCTX *ctx, BUF *dst, u_char *src, size_t slen)
                    110: {
1.5     ! pat       111:        struct zlib_ioctx zio;
1.1       xsa       112:
1.5     ! pat       113:        zio.stream = &ctx->z_instrm;
        !           114:        zio.reset = inflateReset;
        !           115:        zio.io = inflate;
        !           116:        zio.ioflags = Z_FINISH;
1.1       xsa       117:
1.5     ! pat       118:        return cvs_zlib_io(&zio, dst, src, slen);
1.1       xsa       119: }
                    120:
                    121: /*
                    122:  * cvs_zlib_deflate()
                    123:  *
                    124:  * Compress the first <slen> bytes of <src> using the zlib context <ctx> and
                    125:  * store the resulting data in <dst>.
                    126:  * Returns the number of bytes deflated on success, or -1 on failure.
                    127:  */
                    128: int
                    129: cvs_zlib_deflate(CVSZCTX *ctx, BUF *dst, u_char *src, size_t slen)
                    130: {
1.5     ! pat       131:        struct zlib_ioctx zio;
        !           132:
        !           133:        zio.stream = &ctx->z_destrm;
        !           134:        zio.reset = deflateReset;
        !           135:        zio.io = deflate;
        !           136:        zio.ioflags = Z_FINISH;
        !           137:
        !           138:        return cvs_zlib_io(&zio, dst, src, slen);
        !           139: }
        !           140:
        !           141: static int
        !           142: cvs_zlib_io(struct zlib_ioctx *zio, BUF *dst, u_char *src, size_t slen)
        !           143: {
1.1       xsa       144:        int bytes, ret;
                    145:        u_char buf[CVS_ZLIB_BUFSIZE];
1.5     ! pat       146:        z_stream *zstream = zio->stream;
1.1       xsa       147:
                    148:        bytes = 0;
                    149:        cvs_buf_empty(dst);
1.5     ! pat       150:        if ((*zio->reset)(zstream) == Z_STREAM_ERROR)
        !           151:                fatal("%s error: %s", (zio->reset == inflateReset) ?
        !           152:                    "inflate" : "deflate", zstream->msg);
1.1       xsa       153:
1.5     ! pat       154:        zstream->next_in = src;
        !           155:        zstream->avail_in = slen;
1.1       xsa       156:
                    157:        do {
1.5     ! pat       158:                zstream->next_out = buf;
        !           159:                zstream->avail_out = sizeof(buf);
        !           160:                ret = (*zio->io)(zstream, zio->ioflags);
        !           161:                if (ret == Z_MEM_ERROR || ret == Z_STREAM_ERROR ||
        !           162:                    ret == Z_BUF_ERROR || ret == Z_DATA_ERROR)
        !           163:                        fatal("%s error: %s", (zio->reset == inflateReset) ?
        !           164:                            "inflate" : "deflate", zstream->msg);
1.1       xsa       165:
                    166:                if (cvs_buf_append(dst, buf,
1.5     ! pat       167:                    sizeof(buf) - zstream->avail_out) < 0)
1.1       xsa       168:                        return (-1);
1.5     ! pat       169:                bytes += sizeof(buf) - zstream->avail_out;
1.1       xsa       170:        } while (ret != Z_STREAM_END);
                    171:
                    172:        return (bytes);
                    173: }