|  | /***************************************************************************** | 
|  | *  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 |