#include "mawk.h"
#define MAWK_ZFIFO_STAGE 64
/* zmalloc based binary fifo; a linked list of zmalloc'd blocks of writes.
Small writes are cached until they reach MAWK_ZFIFO_STAGE to avoid a lot
of blocks when writing the fifo char-by-char */
typedef struct mawk_zfifo_block_s mawk_zfifo_block_t;
struct mawk_zfifo_block_s {
mawk_zfifo_block_t *next; /* next block to jump to when this one is exhausted */
int size;
int readp; /* next character to read from this buffer */
char buf[1]; /* start of the buffer */
};
typedef struct {
int size, max_size; /* current and maximum size; max size is in data bytes hold by the buffer, there's an overhead of allocation; max_size = -1 means no limit */
char stage_buf[MAWK_ZFIFO_STAGE]; /* staging: buffer small writes to avoid very small zmalloc(); this also assumes read happens in bigger chunks so stage buffer is most likely read at once */
int stage_used;
mawk_zfifo_block_t *head, *tail; /* singly linked list of blocks with head and tail */
int zalloced; /* whether the fifo was zalloc()'d */
} mawk_zfifo_t;
/* set up fifo; if sfifo is NULL, the fifo is zalloc()'d, else all fields
are reset */
mawk_zfifo_t *mawk_zfifo_alloc(mawk_state_t *MAWK, mawk_zfifo_t *sfifo, int max_size);
/* discard all data and free the buffer; if it was auto-zalloc()'d
in mawk_zfifo_alloc(), fifo is zfree()d here */
void mawk_zfifo_free(mawk_state_t *MAWK, mawk_zfifo_t *fifo);
/* append data to the end of a fifo; return size written
(no short write: if max_size prevents the write, no bytes are appended and 0 is returned) */
int mawk_zfifo_write(mawk_state_t *MAWK, mawk_zfifo_t *fifo, const char *data, int size);
/* pop data from the beginning of the fifo; return size read
(short read: when there's not enough data in the fifo) */
int mawk_zfifo_read(mawk_state_t *MAWK, mawk_zfifo_t *fifo, char *data, int size);