/*
 * 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"
#include "log.h"
#include <stddef.h>

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

  d = XMALLOC (MTYPE_BUFFER_DATA, offsetof(struct buffer_data,data[size]));
  d->cp = d->sp = 0;
  return d;
}

static void
buffer_data_free (struct buffer_data *d)
{
  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)
{
  size_t totlen = 0;
  struct buffer_data *data;
  char *s;
  char *p;

  for (data = b->head; data; data = data->next)
    totlen += data->cp - data->sp;
  if (!(s = XMALLOC(MTYPE_TMP, totlen+1)))
    return NULL;
  p = s;
  for (data = b->head; data; data = data->next)
    {
      memcpy(p, data->data + data->sp, data->cp - data->sp);
      p += data->cp - data->sp;
    }
  *p = '\0';
  return s;
}

/* 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)    
    {
      size_t chunk;

      /* If there is no data buffer add it. */
      if (data == NULL || data->cp == b->size)
	{
	  buffer_add (b);
	  data = b->tail;
	}

      chunk = ((size <= (b->size - data->cp)) ? size : (b->size - data->cp));
      memcpy ((data->data + data->cp), ptr, chunk);
      size -= chunk;
      ptr += chunk;
      data->cp += chunk;
    }
  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;
	  b->length -= size;
	  if (data->sp == data->cp)
	    data = data->next;
	  break;
	}
      else
	{
	  iovec[iov_index++].iov_len = data->cp - data->sp;
	  b->length -= (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;

      b->length -= (out->cp-out->sp);
      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;
	  b->length -= 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);
	  b->length -= (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);
}

/* This function (unlike other buffer_flush* functions above) is designed
to work with non-blocking sockets.  It does not attempt to write out
all of the queued data, just a "big" chunk.  It returns 0 if it was
able to empty out the buffers completely, or 1 if more flushing is
required later. */
int
buffer_flush_available(struct buffer *b, int fd)
{

/* These are just reasonable values to make sure a significant amount of
data is written.  There's no need to go crazy and try to write it all
in one shot. */
#ifdef IOV_MAX
#define MAX_CHUNKS ((IOV_MAX >= 16) ? 16 : IOV_MAX)
#else
#define MAX_CHUNKS 16
#endif
#define MAX_FLUSH 131072

  struct buffer_data *d;
  struct buffer_data *next;
  size_t written;
  struct iovec iov[MAX_CHUNKS];
  size_t iovcnt = 0;
  size_t nbyte = 0;

  for (d = b->head; d && (iovcnt < MAX_CHUNKS) && (nbyte < MAX_FLUSH);
       d = d->next, iovcnt++)
    {
      iov[iovcnt].iov_base = d->data+d->sp;
      nbyte += (iov[iovcnt].iov_len = d->cp-d->sp);
    }

  /* only place where written should be sign compared */
  if ((ssize_t)(written = writev(fd,iov,iovcnt)) < 0)
    {
      if ((errno != EAGAIN) && (errno != EINTR))
        zlog_warn("buffer_flush_available write error on fd %d: %s",
		  fd,safe_strerror(errno));
      return 1;
    }

  /* Free printed buffer data. */
  for (d = b->head; (written > 0) && d; d = next)
    {
      if (written < d->cp-d->sp)
        {
	  d->sp += written;
	  b->length -= written;
	  return 1;
	}

      written -= (d->cp-d->sp);
      next = d->next;
      if (next)
	next->prev = NULL;
      else
	b->tail = next;
      b->head = next;

      b->length -= (d->cp-d->sp);
      buffer_data_free (d);
      b->alloc--;
    }

  return (b->head != NULL);

#undef MAX_CHUNKS
#undef MAX_FLUSH
}
