[BACK]Return to deflate.c CVS log [TXT][DIR] Up to [local] / sys / crypto

Annotation of sys/crypto/deflate.c, Revision 1.1

1.1     ! nbrk        1: /* $OpenBSD: deflate.c,v 1.4 2005/03/24 11:43:40 hshoexer Exp $ */
        !             2:
        !             3: /*
        !             4:  * Copyright (c) 2001 Jean-Jacques Bernard-Gundol (jj@wabbitt.org)
        !             5:  *
        !             6:  * Redistribution and use in source and binary forms, with or without
        !             7:  * modification, are permitted provided that the following conditions
        !             8:  * are met:
        !             9:  *
        !            10:  * 1. Redistributions of source code must retain the above copyright
        !            11:  *   notice, this list of conditions and the following disclaimer.
        !            12:  * 2. Redistributions in binary form must reproduce the above copyright
        !            13:  *   notice, this list of conditions and the following disclaimer in the
        !            14:  *   documentation and/or other materials provided with the distribution.
        !            15:  * 3. The name of the author may not be used to endorse or promote products
        !            16:  *   derived from this software without specific prior written permission.
        !            17:  *
        !            18:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
        !            19:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
        !            20:  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
        !            21:  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
        !            22:  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        !            23:  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
        !            24:  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
        !            25:  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
        !            26:  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
        !            27:  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
        !            28:  */
        !            29:
        !            30: /*
        !            31:  * This file contains a wrapper around the deflate algo compression
        !            32:  * functions using the zlib library (see net/zlib.{c,h})
        !            33:  */
        !            34:
        !            35: #include <sys/types.h>
        !            36: #include <sys/malloc.h>
        !            37: #include <sys/param.h>
        !            38: #include <sys/systm.h>
        !            39: #include <net/zlib.h>
        !            40: #include <crypto/deflate.h>
        !            41:
        !            42: int window_inflate = -1 * MAX_WBITS;
        !            43: int window_deflate = -12;
        !            44:
        !            45: /*
        !            46:  * This function takes a block of data and (de)compress it using the deflate
        !            47:  * algorithm
        !            48:  */
        !            49:
        !            50: u_int32_t
        !            51: deflate_global(u_int8_t *data, u_int32_t size, int comp, u_int8_t **out)
        !            52: {
        !            53:        /* comp indicates whether we compress (0) or decompress (1) */
        !            54:
        !            55:        z_stream zbuf;
        !            56:        u_int8_t *output;
        !            57:        u_int32_t count, result;
        !            58:        int error, i = 0, j;
        !            59:        struct deflate_buf buf[ZBUF];
        !            60:
        !            61:        bzero(&zbuf, sizeof(z_stream));
        !            62:        for (j = 0; j < ZBUF; j++)
        !            63:                buf[j].flag = 0;
        !            64:
        !            65:        zbuf.next_in = data;    /* data that is going to be processed */
        !            66:        zbuf.zalloc = z_alloc;
        !            67:        zbuf.zfree = z_free;
        !            68:        zbuf.opaque = Z_NULL;
        !            69:        zbuf.avail_in = size;   /* Total length of data to be processed */
        !            70:
        !            71:        if (comp == 0) {
        !            72:                MALLOC(buf[i].out, u_int8_t *, (u_long) size, M_CRYPTO_DATA,
        !            73:                    M_NOWAIT);
        !            74:                if (buf[i].out == NULL)
        !            75:                        goto bad;
        !            76:                buf[i].size = size;
        !            77:                buf[i].flag = 1;
        !            78:                i++;
        !            79:        } else {
        !            80:                /*
        !            81:                 * Choose a buffer with 4x the size of the input buffer
        !            82:                 * for the size of the output buffer in the case of
        !            83:                 * decompression. If it's not sufficient, it will need to be
        !            84:                 * updated while the decompression is going on
        !            85:                 */
        !            86:
        !            87:                MALLOC(buf[i].out, u_int8_t *, (u_long) (size * 4),
        !            88:                    M_CRYPTO_DATA, M_NOWAIT);
        !            89:                if (buf[i].out == NULL)
        !            90:                        goto bad;
        !            91:                buf[i].size = size * 4;
        !            92:                buf[i].flag = 1;
        !            93:                i++;
        !            94:        }
        !            95:
        !            96:        zbuf.next_out = buf[0].out;
        !            97:        zbuf.avail_out = buf[0].size;
        !            98:
        !            99:        error = comp ? inflateInit2(&zbuf, window_inflate) :
        !           100:            deflateInit2(&zbuf, Z_DEFAULT_COMPRESSION, Z_METHOD,
        !           101:            window_deflate, Z_MEMLEVEL, Z_DEFAULT_STRATEGY, MINCOMP);
        !           102:
        !           103:        if (error != Z_OK)
        !           104:                goto bad;
        !           105:        for (;;) {
        !           106:                error = comp ? inflate(&zbuf, Z_PARTIAL_FLUSH) :
        !           107:                    deflate(&zbuf, Z_PARTIAL_FLUSH);
        !           108:                if (error != Z_OK && error != Z_STREAM_END)
        !           109:                        goto bad;
        !           110:                else if (zbuf.avail_in == 0 && zbuf.avail_out != 0)
        !           111:                        goto end;
        !           112:                else if (zbuf.avail_out == 0 && i < (ZBUF - 1)) {
        !           113:                        /* we need more output space, allocate size */
        !           114:                        MALLOC(buf[i].out, u_int8_t *, (u_long) size,
        !           115:                            M_CRYPTO_DATA, M_NOWAIT);
        !           116:                        if (buf[i].out == NULL)
        !           117:                                goto bad;
        !           118:                        zbuf.next_out = buf[i].out;
        !           119:                        buf[i].size = size;
        !           120:                        buf[i].flag = 1;
        !           121:                        zbuf.avail_out = buf[i].size;
        !           122:                        i++;
        !           123:                } else
        !           124:                        goto bad;
        !           125:        }
        !           126:
        !           127: end:
        !           128:        result = count = zbuf.total_out;
        !           129:
        !           130:        MALLOC(*out, u_int8_t *, (u_long) result, M_CRYPTO_DATA, M_NOWAIT);
        !           131:        if (*out == NULL)
        !           132:                goto bad;
        !           133:        if (comp)
        !           134:                inflateEnd(&zbuf);
        !           135:        else
        !           136:                deflateEnd(&zbuf);
        !           137:        output = *out;
        !           138:        for (j = 0; buf[j].flag != 0; j++) {
        !           139:                if (count > buf[j].size) {
        !           140:                        bcopy(buf[j].out, *out, buf[j].size);
        !           141:                        *out += buf[j].size;
        !           142:                        FREE(buf[j].out, M_CRYPTO_DATA);
        !           143:                        count -= buf[j].size;
        !           144:                } else {
        !           145:                        /* it should be the last buffer */
        !           146:                        bcopy(buf[j].out, *out, count);
        !           147:                        *out += count;
        !           148:                        FREE(buf[j].out, M_CRYPTO_DATA);
        !           149:                        count = 0;
        !           150:                }
        !           151:        }
        !           152:        *out = output;
        !           153:        return result;
        !           154:
        !           155: bad:
        !           156:        *out = NULL;
        !           157:        for (j = 0; buf[j].flag != 0; j++)
        !           158:                FREE(buf[j].out, M_CRYPTO_DATA);
        !           159:        if (comp)
        !           160:                inflateEnd(&zbuf);
        !           161:        else
        !           162:                deflateEnd(&zbuf);
        !           163:        return 0;
        !           164: }
        !           165:
        !           166: void *
        !           167: z_alloc(void *nil, u_int type, u_int size)
        !           168: {
        !           169:        void *ptr;
        !           170:
        !           171:        ptr = malloc(type *size, M_CRYPTO_DATA, M_NOWAIT);
        !           172:        return ptr;
        !           173: }
        !           174:
        !           175: void
        !           176: z_free(void *nil, void *ptr, u_int size)
        !           177: {
        !           178:        free(ptr, M_CRYPTO_DATA);
        !           179: }

CVSweb