/*
 * 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, void *ptr, size_t size)
{
  struct buffer_data *data;

  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, 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, 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);
}
