root/crypto/deflate.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. deflate_global
  2. z_alloc
  3. z_free

    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 }

/* [<][>][^][v][top][bottom][index][help] */