/*
 * Buffering of output and input. 
 * Copyright (C) 1998 Kunihiro Ishiguro
 *
 * This file is part of GNU Zebra.
 *
 * GNU Zebra is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published
 * by the Free Software Foundation; either version 2, or (at your
 * option) any later version.
 * 
 * GNU Zebra is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Zebra; see the file COPYING.  If not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA. 
 */

#include <zebra.h>

#include "memory.h"
#include "buffer.h"

/* Make buffer data. */
struct buffer_data *
buffer_data_new (size_t size)
{
  struct buffer_data *d;

  d = XMALLOC (MTYPE_BUFFER_DATA, sizeof (struct buffer_data));
  memset (d, 0, sizeof (struct buffer_data));
  d->data = XMALLOC (MTYPE_BUFFER_DATA, size);

  return d;
}

void
buffer_data_free (struct buffer_data *d)
{
  if (d->data)
    XFREE (MTYPE_BUFFER_DATA, d->data);
  XFREE (MTYPE_BUFFER_DATA, d);
}

/* Make new buffer. */
struct buffer *
buffer_new (size_t size)
{
  struct buffer *b;

  b = XMALLOC (MTYPE_BUFFER, sizeof (struct buffer));
  memset (b, 0, sizeof (struct buffer));

  b->size = size;

  return b;
}

/* Free buffer. */
void
buffer_free (struct buffer *b)
{
  struct buffer_data *d;
  struct buffer_data *next;

  d = b->head;
  while (d)
    {
      next = d->next;
      buffer_data_free (d);
      d = next;
    }

  d = b->unused_head;
  while (d)
    {
      next = d->next;
      buffer_data_free (d);
      d = next;
    }
  
  XFREE (MTYPE_BUFFER, b);
}

/* Make string clone. */
char *
buffer_getstr (struct buffer *b)
{
  return strdup ((char *)b->head->data);
}

/* Return 1 if buffer is empty. */
int
buffer_empty (struct buffer *b)
{
  if (b->tail == NULL || b->tail->cp == b->tail->sp)
    return 1;
  else
    return 0;
}

/* Clear and free all allocated data. */
void
buffer_reset (struct buffer *b)
{
  struct buffer_data *data;
  struct buffer_data *next;
  
  for (data = b->head; data; data = next)
    {
      next = data->next;
      buffer_data_free (data);
    }
  b->head = b->tail = NULL;
  b->alloc = 0;
  b->length = 0;
}

/* Add buffer_data to the end of buffer. */
void
buffer_add (struct buffer *b)
{
  struct buffer_data *d;

  d = buffer_data_new (b->size);

  if (b->tail == NULL)
    {
      d->prev = NULL;
      d->next = NULL;
      b->head = d;
      b->tail = d;
    }
  else
    {
      d->prev = b->tail;
      d->next = NULL;

      b->tail->next = d;
      b->tail = d;
    }

  b->alloc++;
}

/* Write data to buffer. */
int
buffer_write (struct buffer *b, const void *p, size_t size)
{
  struct buffer_data *data;
  const char *ptr = p;
  data = b->tail;
  b->length += size;

  /* We use even last one byte of data buffer. */
  while (size)    
    {
      /* If there is no data buffer add it. */
      if (data == NULL || data->cp == b->size)
	{
	  buffer_add (b);
	  data = b->tail;
	}

      /* Last data. */
      if (size <= (b->size - data->cp))
	{
	  memcpy ((data->data + data->cp), ptr, size);

	  data->cp += size;
	  size = 0;
	}
      else
	{
	  memcpy ((data->data + data->cp), ptr, (b->size - data->cp));

	  size -= (b->size - data->cp);
	  ptr += (b->size - data->cp);

	  data->cp = b->size;
	}
    }
  return 1;
}

/* Insert character into the buffer. */
int
buffer_putc (struct buffer *b, u_char c)
{
  buffer_write (b, &c, 1);
  return 1;
}

/* Insert word (2 octets) into ther buffer. */
int
buffer_putw (struct buffer *b, u_short c)
{
  buffer_write (b, (char *)&c, 2);
  return 1;
}

/* Put string to the buffer. */
int
buffer_putstr (struct buffer *b, const char *c)
{
  size_t size;

  size = strlen (c);
  buffer_write (b, (void *) c, size);
  return 1;
}

/* Flush specified size to the fd. */
void
buffer_flush (struct buffer *b, int fd, size_t size)
{
  int iov_index;
  struct iovec *iovec;
  struct buffer_data *data;
  struct buffer_data *out;
  struct buffer_data *next;

  iovec = malloc (sizeof (struct iovec) * b->alloc);
  iov_index = 0;

  for (data = b->head; data; data = data->next)
    {
      iovec[iov_index].iov_base = (char *)(data->data + data->sp);

      if (size <= (data->cp - data->sp))
	{
	  iovec[iov_index++].iov_len = size;
	  data->sp += size;
	  if (data->sp == data->cp)
	    data = data->next;
	  break;
	}
      else
	{
	  iovec[iov_index++].iov_len = data->cp - data->sp;
	  size -= data->cp - data->sp;
	  data->sp = data->cp;
	}
    }

  /* Write buffer to the fd. */
  writev (fd, iovec, iov_index);

  /* Free printed buffer data. */
  for (out = b->head; out && out != data; out = next)
    {
      next = out->next;
      if (next)
	next->prev = NULL;
      else
	b->tail = next;
      b->head = next;

      buffer_data_free (out);
      b->alloc--;
    }

  free (iovec);
}

/* Flush all buffer to the fd. */
int
buffer_flush_all (struct buffer *b, int fd)
{
  int ret;
  struct buffer_data *d;
  int iov_index;
  struct iovec *iovec;

  if (buffer_empty (b))
    return 0;

  iovec = malloc (sizeof (struct iovec) * b->alloc);
  iov_index = 0;

  for (d = b->head; d; d = d->next)
    {
      iovec[iov_index].iov_base = (char *)(d->data + d->sp);
      iovec[iov_index].iov_len = d->cp - d->sp;
      iov_index++;
    }
  ret = writev (fd, iovec, iov_index);

  free (iovec);

  buffer_reset (b);

  return ret;
}

/* Flush all buffer to the fd. */
int
buffer_flush_vty_all (struct buffer *b, int fd, int erase_flag,
		      int no_more_flag)
{
  int nbytes;
  int iov_index;
  struct iovec *iov;
  struct iovec small_iov[3];
  char more[] = " --More-- ";
  char erase[] = { 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
		   ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
		   0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08};
  struct buffer_data *data;
  struct buffer_data *out;
  struct buffer_data *next;

  /* For erase and more data add two to b's buffer_data count.*/
  if (b->alloc == 1)
    iov = small_iov;
  else
    iov = XCALLOC (MTYPE_TMP, sizeof (struct iovec) * (b->alloc + 2));

  data = b->head;
  iov_index = 0;

  /* Previously print out is performed. */
  if (erase_flag)
    {
      iov[iov_index].iov_base = erase;
      iov[iov_index].iov_len = sizeof erase;
      iov_index++;
    }

  /* Output data. */
  for (data = b->head; data; data = data->next)
    {
      iov[iov_index].iov_base = (char *)(data->data + data->sp);
      iov[iov_index].iov_len = data->cp - data->sp;
      iov_index++;
    }

  /* In case of `more' display need. */
  if (! buffer_empty (b) && !no_more_flag)
    {
      iov[iov_index].iov_base = more;
      iov[iov_index].iov_len = sizeof more;
      iov_index++;
    }

  /* We use write or writev*/
  nbytes = writev (fd, iov, iov_index);

  /* Error treatment. */
  if (nbytes < 0)
    {
      if (errno == EINTR)
	;
      if (errno == EWOULDBLOCK)
	;
    }

  /* Free printed buffer data. */
  for (out = b->head; out && out != data; out = next)
    {
      next = out->next;
      if (next)
	next->prev = NULL;
      else
	b->tail = next;
      b->head = next;

      buffer_data_free (out);
      b->alloc--;
    }

  if (iov != small_iov)
    XFREE (MTYPE_TMP, iov);

  return nbytes;
}

/* Flush buffer to the file descriptor.  Mainly used from vty
   interface. */
int
buffer_flush_vty (struct buffer *b, int fd, unsigned int size, 
		  int erase_flag, int no_more_flag)
{
  int nbytes;
  int iov_index;
  struct iovec *iov;
  struct iovec small_iov[3];
  char more[] = " --More-- ";
  char erase[] = { 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
		   ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
		   0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08};
  struct buffer_data *data;
  struct buffer_data *out;
  struct buffer_data *next;

#ifdef  IOV_MAX
  int iov_size;
  int total_size;
  struct iovec *c_iov;
  int c_nbytes;
#endif /* IOV_MAX */

  /* For erase and more data add two to b's buffer_data count.*/
  if (b->alloc == 1)
    iov = small_iov;
  else
    iov = XCALLOC (MTYPE_TMP, sizeof (struct iovec) * (b->alloc + 2));

  data = b->head;
  iov_index = 0;

  /* Previously print out is performed. */
  if (erase_flag)
    {
      iov[iov_index].iov_base = erase;
      iov[iov_index].iov_len = sizeof erase;
      iov_index++;
    }

  /* Output data. */
  for (data = b->head; data; data = data->next)
    {
      iov[iov_index].iov_base = (char *)(data->data + data->sp);

      if (size <= (data->cp - data->sp))
	{
	  iov[iov_index++].iov_len = size;
	  data->sp += size;
	  if (data->sp == data->cp)
	    data = data->next;
	  break;
	}
      else
	{
	  iov[iov_index++].iov_len = data->cp - data->sp;
	  size -= (data->cp - data->sp);
	  data->sp = data->cp;
	}
    }

  /* In case of `more' display need. */
  if (!buffer_empty (b) && !no_more_flag)
    {
      iov[iov_index].iov_base = more;
      iov[iov_index].iov_len = sizeof more;
      iov_index++;
    }

  /* We use write or writev*/

#ifdef IOV_MAX
  /* IOV_MAX are normally defined in <sys/uio.h> , Posix.1g.
     example: Solaris2.6 are defined IOV_MAX size at 16.     */
  c_iov = iov;
  total_size = iov_index;
  nbytes = 0;

  while( total_size > 0 )
    {
       /* initialize write vector size at once */
       iov_size = ( total_size > IOV_MAX ) ? IOV_MAX : total_size;

       c_nbytes = writev (fd, c_iov, iov_size );

       if( c_nbytes < 0 )
         {
           if(errno == EINTR)
             ;
             ;
           if(errno == EWOULDBLOCK)
             ;
             ;
           nbytes = c_nbytes;
           break;

         }

        nbytes += c_nbytes;

       /* move pointer io-vector */
       c_iov += iov_size;
       total_size -= iov_size;
    }
#else  /* IOV_MAX */
   nbytes = writev (fd, iov, iov_index);

  /* Error treatment. */
  if (nbytes < 0)
    {
      if (errno == EINTR)
	;
      if (errno == EWOULDBLOCK)
	;
    }
#endif /* IOV_MAX */

  /* Free printed buffer data. */
  for (out = b->head; out && out != data; out = next)
    {
      next = out->next;
      if (next)
	next->prev = NULL;
      else
	b->tail = next;
      b->head = next;

      buffer_data_free (out);
      b->alloc--;
    }

  if (iov != small_iov)
    XFREE (MTYPE_TMP, iov);

  return nbytes;
}

/* Calculate size of outputs then flush buffer to the file
   descriptor. */
int
buffer_flush_window (struct buffer *b, int fd, int width, int height, 
		     int erase, int no_more)
{
  unsigned long cp;
  unsigned long size;
  int lp;
  int lineno;
  struct buffer_data *data;

  if (height >= 2)
    height--;

  /* We have to calculate how many bytes should be written. */
  lp = 0;
  lineno = 0;
  size = 0;
  
  for (data = b->head; data; data = data->next)
    {
      cp = data->sp;

      while (cp < data->cp)
	{
	  if (data->data[cp] == '\n' || lp == width)
	    {
	      lineno++;
	      if (lineno == height)
		{
		  cp++;
		  size++;
		  goto flush;
		}
	      lp = 0;
	    }
	  cp++;
	  lp++;
	  size++;
	}
    }

  /* Write data to the file descriptor. */
 flush:

  return buffer_flush_vty (b, fd, size, erase, no_more);
}
