/*

buffer.c

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

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

Created: Sat Mar 18 04:15:33 1995 ylo

Functions for manipulating fifo buffers (that can grow if needed).

*/

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

#include "xmalloc.h"
#include "buffer.h"
#include "ssh.h"

/* Initializes the buffer structure. */

void buffer_init(Buffer *buffer)
{
  buffer->alloc = 4096;
  buffer->buf = xmalloc(buffer->alloc);
  buffer->offset = 0;
  buffer->end = 0;
}

/* Frees any memory used for the buffer. */

void buffer_free(Buffer *buffer)
{
  memset(buffer->buf, 0, buffer->alloc);
  xfree(buffer->buf);
}

/* Clears any data from the buffer, making it empty.  This does not actually
   zero the memory. */

void buffer_clear(Buffer *buffer)
{
  buffer->offset = 0;
  buffer->end = 0;
}

/* Appends data to the buffer, expanding it if necessary. */

void buffer_append(Buffer *buffer, const char *data, unsigned int len)
{
  char *cp;
  buffer_append_space(buffer, &cp, len);
  memcpy(cp, data, len);
}

/* Appends space to the buffer, expanding the buffer if necessary.
   This does not actually copy the data into the buffer, but instead
   returns a pointer to the allocated region. */

void buffer_append_space(Buffer *buffer, char **datap, unsigned int len)
{
  /* If the buffer is empty, start using it from the beginning. */
  if (buffer->offset == buffer->end)
    {
      buffer->offset = 0;
      buffer->end = 0;
    }

 restart:
  /* If there is enough space to store all data, store it now. */
  if (buffer->end + len < buffer->alloc)
    {
      *datap = buffer->buf + buffer->end;
      buffer->end += len;
      return;
    }

  /* If the buffer is quite empty, but all data is at the end, move the
     data to the beginning and retry. */
  if (buffer->offset > buffer->alloc / 2)
    {
      memmove(buffer->buf, buffer->buf + buffer->offset,
	      buffer->end - buffer->offset);
      buffer->end -= buffer->offset;
      buffer->offset = 0;
      goto restart;
    }

  /* Increase the size of the buffer and retry. */
  buffer->alloc += len + 32768;
  buffer->buf = xrealloc(buffer->buf, buffer->alloc);
  goto restart;
}

/* Returns the number of bytes of data in the buffer. */

unsigned int buffer_len(Buffer *buffer)
{
  return buffer->end - buffer->offset;
}

/* Gets data from the beginning of the buffer. */

void buffer_get(Buffer *buffer, char *buf, unsigned int len)
{
  if (len > buffer->end - buffer->offset)
    fatal("buffer_get trying to get more bytes than in buffer");
  memcpy(buf, buffer->buf + buffer->offset, len);
  buffer->offset += len;
}

/* Consumes the given number of bytes from the beginning of the buffer. */

void buffer_consume(Buffer *buffer, unsigned int bytes)
{
  if (bytes > buffer->end - buffer->offset)
    fatal("buffer_get trying to get more bytes than in buffer");
  buffer->offset += bytes;
}  

/* Consumes the given number of bytes from the end of the buffer. */

void buffer_consume_end(Buffer *buffer, unsigned int bytes)
{
  if (bytes > buffer->end - buffer->offset)
    fatal("buffer_get trying to get more bytes than in buffer");
  buffer->end -= bytes;
}  

/* Returns a pointer to the first used byte in the buffer. */

char *buffer_ptr(Buffer *buffer)
{
  return buffer->buf + buffer->offset;
}

/* Dumps the contents of the buffer to stderr. */

void buffer_dump(Buffer *buffer)
{
  int i;
  unsigned char *ucp = (unsigned char *)buffer->buf;
  
  for (i = buffer->offset; i < buffer->end; i++)
    fprintf(stderr, " %02x", ucp[i]);
  fprintf(stderr, "\n");
}
