/*
 * Buffering to 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.
 */

#pragma once

#include <sys/types.h>

/* Create a new buffer.  Memory will be allocated in chunks of the given
   size.  If the argument is 0, the library will supply a reasonable
   default size suitable for buffering socket I/O. */
struct buffer *buffer_new(void *ctx, size_t);

/* Free all data in the buffer. */
void buffer_reset(struct buffer *);

/* This function first calls buffer_reset to release all buffered data.
   Then it frees the struct buffer itself. */
void buffer_free(struct buffer *);

/* Add the given data to the end of the buffer. */
extern void buffer_put(struct buffer *, const void *, size_t);
/* Add a single character to the end of the buffer. */
extern void buffer_putc(struct buffer *, unsigned char);
/* Add a NUL-terminated string to the end of the buffer. */
extern void buffer_putstr(struct buffer *, const char *);

/* Combine all accumulated (and unflushed) data inside the buffer into a
   single NUL-terminated string allocated using XMALLOC(MTYPE_TMP).  Note
   that this function does not alter the state of the buffer, so the data
   is still inside waiting to be flushed. */
char *buffer_getstr(struct buffer *);

/* Returns 1 if there is no pending data in the buffer.  Otherwise returns 0. */
int buffer_empty(struct buffer *);

typedef enum {
	/* An I/O error occurred.  The buffer should be destroyed and the
	   file descriptor should be closed. */
	BUFFER_ERROR = -1,

	/* The data was written successfully, and the buffer is now empty
	   (there is no pending data waiting to be flushed). */
	BUFFER_EMPTY = 0,

	/* There is pending data in the buffer waiting to be flushed.  Please
	   try flushing the buffer when select indicates that the file descriptor
	   is writeable. */
	BUFFER_PENDING = 1
} buffer_status_t;

/* Try to write this data to the file descriptor.  Any data that cannot
   be written immediately is added to the buffer queue. */
extern buffer_status_t buffer_write(struct buffer *, int fd,
				    const void *, size_t);

/* This function attempts to flush some (but perhaps not all) of
   the queued data to the given file descriptor. */
extern buffer_status_t buffer_flush_available(struct buffer *, int fd);

/* The following 2 functions (buffer_flush_all and buffer_flush_window)
   are for use in lib/vty.c only.  They should not be used elsewhere. */

/* Call buffer_flush_available repeatedly until either all data has been
   flushed, or an I/O error has been encountered, or the operation would
   block. */
extern buffer_status_t buffer_flush_all(struct buffer *, int fd);

/* Attempt to write enough data to the given fd to fill a window of the
   given width and height (and remove the data written from the buffer).

   If !no_more, then a message saying " --More-- " is appended.
   If erase is true, then first overwrite the previous " --More-- " message
   with spaces.

   Any write error (including EAGAIN or EINTR) will cause this function
   to return -1 (because the logic for handling the erase and more features
   is too complicated to retry the write later).
*/
extern buffer_status_t buffer_flush_window(struct buffer *, int fd, int width,
					   int height, int erase, int no_more);
