/*

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.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");
}
