blob: ba0fed61a0a4a54600269d3a48a33ad63b97006c [file] [log] [blame]
/*****************************************************************************
* cbuf.h
*****************************************************************************
* Copyright (C) 2002-2005 The Regents of the University of California.
* Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
* Written by Chris Dunlap <cdunlap@llnl.gov>.
*
* This file is from LSD-Tools, the LLNL Software Development Toolbox.
*
* LSD-Tools 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 of the License, or (at your option)
* any later version.
*
* In addition, as a special exception, the copyright holders give permission
* to link the code of portions of this program with the OpenSSL library under
* certain conditions as described in each individual source file, and
* distribute linked combinations including the two. You must obey the GNU
* General Public License in all respects for all of the code used other than
* OpenSSL. If you modify file(s) with this exception, you may extend this
* exception to your version of the file(s), but you are not obligated to do
* so. If you do not wish to do so, delete this exception statement from your
* version. If you delete this exception statement from all source files in
* the program, then also delete it here.
*
* LSD-Tools 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 LSD-Tools; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*****************************************************************************/
#ifndef LSD_CBUF_H
#define LSD_CBUF_H
/*
* Cbuf is a circular-buffer capable of dynamically resizing itself.
* Unread data in the buffer will be overwritten once the cbuf has
* reached its maximum size or is unable to allocate additional memory.
*
* The CBUF_OPT_OVERWRITE option specifies how unread cbuf data will
* be overwritten. If set to CBUF_NO_DROP, unread data will never be
* overwritten; writes into the cbuf will return -1 with ENOSPC. If set
* to CBUF_WRAP_ONCE, a single write operation will wrap-around the buffer
* at most once, and up to cbuf_used() bytes of data may be overwritten.
* If set to CBUF_WRAP_MANY, a single write operation will wrap-around the
* buffer as many times as needed in order to write all of the data.
*
* These routines are thread-safe.
*/
/****************
* Data Types *
****************/
typedef struct cbuf cbuf_t; /* circular-buffer opaque data type */
typedef enum { /* cbuf option names */
CBUF_OPT_OVERWRITE
} cbuf_opt_t;
typedef enum { /* CBUF_OPT_OVERWRITE values: */
CBUF_NO_DROP, /* -never drop data, ENOSPC if full */
CBUF_WRAP_ONCE, /* -drop data, wrapping at most once */
CBUF_WRAP_MANY /* -drop data, wrapping as needed */
} cbuf_overwrite_t;
/***************
* Functions *
***************/
/*
* Creates and returns a new circular buffer, or lsd_nomem_error() on failure.
* The buffer is initially allocated to hold [minsize] bytes of data,
* but can attempt to grow up to [maxsize] bytes before overwriting data.
* Set minsize = maxsize to prevent cbuf from dynamically resizing itself.
* The default overwrite option behavior is CBUF_WRAP_MANY.
* Abandoning a cbuf without calling cbuf_destroy() will cause a memory leak.
*/
extern cbuf_t *cbuf_create(int minsize, int maxsize);
/*
* Destroys the circular buffer [cb].
*/
extern void cbuf_destroy(cbuf_t *cb);
/*
* Flushes all data (including replay data) in [cb].
*/
extern void cbuf_flush(cbuf_t *cb);
/*
* Returns the maximum size of the buffer allocated to [cb]
* (ie, the number of bytes it can currently hold).
*/
extern int cbuf_size(cbuf_t *cb);
/*
* Returns the number of bytes in [cb] available for writing before unread
* data is overwritten (assuming the cbuf can resize itself if needed).
*/
extern int cbuf_free(cbuf_t *cb);
/*
* Returns the number of bytes in [cb] available for reading.
*/
extern int cbuf_used(cbuf_t *cb);
/*
* Returns the number of lines in [cb] available for reading.
*/
extern int cbuf_lines_used(cbuf_t *cb);
/*
* Returns the number of bytes in [cb] available for replaying/rewinding.
*/
extern int cbuf_reused(cbuf_t *cb);
/*
* Returns the number of lines in [cb] available for replaying/rewinding.
*/
extern int cbuf_lines_reused(cbuf_t *cb);
/*
* Returns non-zero if [cb] is empty; o/w, returns zero.
*/
extern int cbuf_is_empty(cbuf_t *cb);
/*
* Gets the [name] option for [cb] and sets [value] to the result.
* Returns 0 on success, or -1 on error (with errno set).
*/
extern int cbuf_opt_get(cbuf_t *cb, cbuf_opt_t name, int *value);
/*
* Sets the [name] option for [cb] to [value].
* Returns 0 on success, or -1 on error (with errno set).
*/
extern int cbuf_opt_set(cbuf_t *cb, cbuf_opt_t name, int value);
/*
* Discards up to [len] bytes of unread data from [src];
* if [len] is -1, all unread data will be dropped.
* Dropped data is still available via the replay buffer.
* Returns the number of bytes dropped, or -1 on error (with errno set).
*/
extern int cbuf_drop(cbuf_t *src, int len);
/*
* Reads up to [len] bytes of data from the [src] cbuf into [dstbuf],
* but does not consume the data read from the cbuf.
* The "peek" can be committed to the cbuf via a call to cbuf_drop(),
* but the peek+drop combination is not atomic.
* Returns the number of bytes read, or -1 on error (with errno set).
*/
extern int cbuf_peek(cbuf_t *src, void *dstbuf, int len);
/*
* Reads up to [len] bytes of data from the [src] cbuf into [dstbuf].
* Returns the number of bytes read, or -1 on error (with errno set).
*/
extern int cbuf_read(cbuf_t *src, void *dstbuf, int len);
/*
* Replays up to [len] bytes of previously read data from the [src] cbuf
* into [dstbuf].
* Returns the number of bytes replayed, or -1 on error (with errno set).
*/
extern int cbuf_replay(cbuf_t *src, void *dstbuf, int len);
/*
* Rewinds [src] by up to [len] bytes, placing previously read data back in
* the unread data buffer; if [len] is -1, all replay data will be rewound.
* Returns the number of bytes rewound, or -1 on error (with errno set).
*/
extern int cbuf_rewind(cbuf_t *src, int len);
/*
* Writes up to [len] bytes of data from [srcbuf] into the [dst] cbuf
* according to dst's CBUF_OPT_OVERWRITE behavior.
* Returns the number of bytes written, or -1 on error (with errno set).
* Sets [ndropped] (if not NULL) to the number of bytes overwritten.
*/
extern int cbuf_write(cbuf_t *dst, void *srcbuf, int len, int *ndropped);
/*
* Discards the specified [lines] of data from [src]. If [lines] is -1,
* discards the maximum number of lines comprised of up to [len] characters.
* Dropped data is still available via the replay buffer.
* Returns the number of bytes dropped, or -1 on error (with errno set).
* Returns 0 if the number of lines is not available (ie, all or none).
*/
extern int cbuf_drop_line(cbuf_t *src, int len, int lines);
/*
* Reads the specified [lines] of data from the [src] cbuf into [dstbuf],
* but does not consume the data read from the cbuf. If [lines] is -1,
* reads the maximum number of lines that [dstbuf] can hold. The buffer
* will be NUL-terminated and contain at most ([len] - 1) characters.
* The "peek" can be committed to the cbuf via a call to cbuf_drop(),
* but the peek+drop combination is not atomic.
* Returns strlen of the line(s) on success; truncation occurred if >= [len].
* Returns 0 if the number of lines is not available (ie, all or none).
* Returns -1 on error (with errno set).
*/
extern int cbuf_peek_line(cbuf_t *src, char *dstbuf, int len, int lines);
/*
* Reads the specified [lines] of data from the [src] cbuf into [dstbuf].
* If [lines] is -1, reads the maximum number of lines that [dstbuf]
* can hold. The buffer will be NUL-terminated and contain at most
* ([len] - 1) characters.
* Returns strlen of the line(s) on success; truncation occurred if >= [len],
* in which case excess line data is discarded. Returns 0 if the number
* of lines is not available (ie, all or none), in which case no data is
* consumed. Returns -1 on error (with errno set).
*/
extern int cbuf_read_line(cbuf_t *src, char *dstbuf, int len, int lines);
/*
* Replays the specified [lines] of data from the [src] cbuf into [dstbuf].
* If [lines] is -1, replays the maximum number of lines that [dstbuf]
* can hold. A newline will be appended to [dstbuf] if the last (ie, most
* recently read) line does not contain a trailing newline. The buffer
* will be NUL-terminated and contain at most ([len] - 1) characters.
* Returns strlen of the line(s) on success; truncation occurred if >= [len].
* Returns 0 if the number of lines is not available (ie, all or none).
* Returns -1 on error (with errno set).
*/
extern int cbuf_replay_line(cbuf_t *src, char *dstbuf, int len, int lines);
/*
* Rewinds [src] by the specified [lines] of data, placing previously read
* data back in the unread data buffer. If [lines] is -1, rewinds the
* maximum number of lines comprised of up to [len] characters.
* Returns the number of bytes rewound, or -1 on error (with errno set).
* Returns 0 if the number of lines is not available (ie, all or none).
*/
extern int cbuf_rewind_line(cbuf_t *src, int len, int lines);
/*
* Writes the entire NUL-terminated [srcbuf] string into the [dst] cbuf
* according to dst's CBUF_OPT_OVERWRITE behavior. A newline will be
* appended to the cbuf if [srcbuf] does not contain a trailing newline.
* Returns the number of bytes written, or -1 or error (with errno set).
* Sets [ndropped] (if not NULL) to the number of bytes overwritten.
*/
extern int cbuf_write_line(cbuf_t *dst, char *srcbuf, int *ndropped);
/*
* Reads up to [len] bytes of data from the [src] cbuf into the file
* referenced by the [dstfd] file descriptor, but does not consume the
* data read from the cbuf. If [len] is -1, it will be set to the number
* of [src] bytes available for reading.
* The "peek" can be committed to the cbuf via a call to cbuf_drop(),
* but the peek+drop combination is not atomic.
* Returns the number of bytes read, or -1 on error (with errno set).
*/
extern int cbuf_peek_to_fd(cbuf_t *src, int dstfd, int len);
/*
* Reads up to [len] bytes of data from the [src] cbuf into the file
* referenced by the [dstfd] file descriptor. If [len] is -1, it will
* be set to the number of [src] bytes available for reading.
* Returns the number of bytes read, or -1 on error (with errno set).
*/
extern int cbuf_read_to_fd(cbuf_t *src, int dstfd, int len);
/*
* Replays up to [len] bytes of previously read data from the [src] cbuf into
* the file referenced by the [dstfd] file descriptor. If [len] is -1, it
* will be set to the maximum number of [src] bytes available for replay.
* Returns the number of bytes replayed, or -1 on error (with errno set).
*/
extern int cbuf_replay_to_fd(cbuf_t *src, int dstfd, int len);
/*
* Writes up to [len] bytes of data from the file referenced by the
* [srcfd] file descriptor into the [dst] cbuf according to dst's
* CBUF_OPT_OVERWRITE behavior. If [len] is -1, it will be set to
* an appropriate chunk size.
* Returns the number of bytes written, 0 on EOF, or -1 on error (with errno).
* Sets [ndropped] (if not NULL) to the number of bytes overwritten.
*/
extern int cbuf_write_from_fd(cbuf_t *dst, int srcfd, int len, int *ndropped);
/*
* Copies up to [len] bytes of data from the [src] cbuf into the [dst] cbuf
* according to dst's CBUF_OPT_OVERWRITE behavior. If [len] is -1,
* it will be set to the number of [src] bytes available for reading.
* Returns the number of bytes copied, or -1 on error (with errno set).
* Sets [ndropped] (if not NULL) to the number of [dst] bytes overwritten.
*/
extern int cbuf_copy(cbuf_t *src, cbuf_t *dst, int len, int *ndropped);
/*
* Moves up to [len] bytes of data from the [src] cbuf into the [dst] cbuf
* according to dst's CBUF_OPT_OVERWRITE behavior. If [len] is -1,
* it will be set to the number of [src] bytes available for reading.
* Returns the number of bytes moved, or -1 on error (with errno set).
* Sets [ndropped] (if not NULL) to the number of [dst] bytes overwritten.
*/
extern int cbuf_move(cbuf_t *src, cbuf_t *dst, int len, int *ndropped);
#endif