/*

compress.c

Author: Tatu Ylonen <ylo@cs.hut.fi>

Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
                   All rights reserved

Created: Wed Oct 25 22:12:46 1995 ylo

Interface to packet compression for ssh.

*/

#include "includes.h"
RCSID("$Id: compress.c,v 1.1.1.1 1999/10/27 03:42:44 damien Exp $");

#include "ssh.h"
#include "buffer.h"
#include "zlib.h"

static z_stream incoming_stream;
static z_stream outgoing_stream;

/* Initializes compression; level is compression level from 1 to 9 (as in
   gzip). */

void buffer_compress_init(int level)
{
  debug("Enabling compression at level %d.", level);
  if (level < 1 || level > 9)
    fatal("Bad compression level %d.", level);
  inflateInit(&incoming_stream);
  deflateInit(&outgoing_stream, level);
}

/* Frees any data structures allocated for compression. */

void buffer_compress_uninit()
{
  debug("compress outgoing: raw data %lu, compressed %lu, factor %.2f",
	outgoing_stream.total_in, outgoing_stream.total_out,
	outgoing_stream.total_in == 0 ? 0.0 :
	 (double)outgoing_stream.total_out / outgoing_stream.total_in);
  debug("compress incoming: raw data %lu, compressed %lu, factor %.2f",
	incoming_stream.total_out, incoming_stream.total_in,
	incoming_stream.total_out == 0 ? 0.0 :
	  (double)incoming_stream.total_in / incoming_stream.total_out);
  inflateEnd(&incoming_stream);
  deflateEnd(&outgoing_stream);
}

/* Compresses the contents of input_buffer into output_buffer.  All
   packets compressed using this function will form a single
   compressed data stream; however, data will be flushed at the end of
   every call so that each output_buffer can be decompressed
   independently (but in the appropriate order since they together
   form a single compression stream) by the receiver.  This appends
   the compressed data to the output buffer. */

void buffer_compress(Buffer *input_buffer, Buffer *output_buffer)
{
  char buf[4096];
  int status;

  /* This case is not handled below. */
  if (buffer_len(input_buffer) == 0)
    return;

  /* Input is the contents of the input buffer. */
  outgoing_stream.next_in = buffer_ptr(input_buffer);
  outgoing_stream.avail_in = buffer_len(input_buffer);

  /* Loop compressing until deflate() returns with avail_out != 0. */
  do
    {
      /* Set up fixed-size output buffer. */
      outgoing_stream.next_out = buf;
      outgoing_stream.avail_out = sizeof(buf);

      /* Compress as much data into the buffer as possible. */
      status = deflate(&outgoing_stream, Z_PARTIAL_FLUSH);
      switch (status)
	{
	case Z_OK:
	  /* Append compressed data to output_buffer. */
	  buffer_append(output_buffer, buf,
			sizeof(buf) - outgoing_stream.avail_out);
	  break;
	case Z_STREAM_END:
	  fatal("buffer_compress: deflate returned Z_STREAM_END");
	  /*NOTREACHED*/
	case Z_STREAM_ERROR:
	  fatal("buffer_compress: deflate returned Z_STREAM_ERROR");
	  /*NOTREACHED*/
	case Z_BUF_ERROR:
	  fatal("buffer_compress: deflate returned Z_BUF_ERROR");
	  /*NOTREACHED*/
	default:
	  fatal("buffer_compress: deflate returned %d", status);
	  /*NOTREACHED*/
	}
    }
  while (outgoing_stream.avail_out == 0);
}

/* Uncompresses the contents of input_buffer into output_buffer.  All
   packets uncompressed using this function will form a single
   compressed data stream; however, data will be flushed at the end of
   every call so that each output_buffer.  This must be called for the
   same size units that the buffer_compress was called, and in the
   same order that buffers compressed with that.  This appends the
   uncompressed data to the output buffer. */

void buffer_uncompress(Buffer *input_buffer, Buffer *output_buffer)
{
  char buf[4096];
  int status;

  incoming_stream.next_in = buffer_ptr(input_buffer);
  incoming_stream.avail_in = buffer_len(input_buffer);

  incoming_stream.next_out = buf;
  incoming_stream.avail_out = sizeof(buf);

  for (;;)
    {
      status = inflate(&incoming_stream, Z_PARTIAL_FLUSH);
      switch (status)
	{
	case Z_OK:
	  buffer_append(output_buffer, buf,
			sizeof(buf) - incoming_stream.avail_out);
	  incoming_stream.next_out = buf;
	  incoming_stream.avail_out = sizeof(buf);
	  break;
	case Z_STREAM_END:
	  fatal("buffer_uncompress: inflate returned Z_STREAM_END");
	  /*NOTREACHED*/
	case Z_DATA_ERROR:
	  fatal("buffer_uncompress: inflate returned Z_DATA_ERROR");
	  /*NOTREACHED*/
	case Z_STREAM_ERROR:
	  fatal("buffer_uncompress: inflate returned Z_STREAM_ERROR");
	  /*NOTREACHED*/
	case Z_BUF_ERROR:
	  /* Comments in zlib.h say that we should keep calling inflate()
	     until we get an error.  This appears to be the error that we
	     get. */
	  return;
	case Z_MEM_ERROR:
	  fatal("buffer_uncompress: inflate returned Z_MEM_ERROR");
	  /*NOTREACHED*/
	default:
	  fatal("buffer_uncompress: inflate returned %d", status);
	}
    }
}

