Blame src/buff.c

Packit e8bc57
/** \file buff.c
Packit e8bc57
 * implementation of the buff type, a buffer for arbitrary strings
Packit e8bc57
 * and actually a superset of word_t
Packit e8bc57
 *
Packit e8bc57
 * \author David Relson <relson@osagesoftware.com>
Packit e8bc57
 * \author Matthias Andree <matthias.andree@gmx.de> (buff_fgetsl)
Packit e8bc57
 */
Packit e8bc57
Packit e8bc57
#include "common.h"
Packit e8bc57
Packit e8bc57
#include <stdlib.h>
Packit e8bc57
Packit e8bc57
#include "buff.h"
Packit e8bc57
#include "fgetsl.h"
Packit e8bc57
#include "xmalloc.h"
Packit e8bc57
Packit e8bc57
#define BOGO_ASSERT(expr, msg) if (!(expr)) { fprintf(stderr, "%s: %s:%d %s\n", progname, __FILE__, __LINE__, msg); abort(); }
Packit e8bc57
Packit e8bc57
/* Function Definitions */
Packit e8bc57
buff_t *buff_init(buff_t *self, byte *buff, uint used, uint size)
Packit e8bc57
{
Packit e8bc57
    self->t.u.text = buff;
Packit e8bc57
    self->t.leng = used;
Packit e8bc57
    self->read = 0;
Packit e8bc57
    self->size = size;
Packit e8bc57
    return self;
Packit e8bc57
}
Packit e8bc57
Packit e8bc57
buff_t *buff_new(byte *buff, uint used, uint size)
Packit e8bc57
{
Packit e8bc57
    buff_t *self = (buff_t *)xmalloc(sizeof(buff_t));
Packit e8bc57
    buff_init(self, buff, used, size);
Packit e8bc57
    return self;
Packit e8bc57
}
Packit e8bc57
Packit e8bc57
void buff_free(buff_t *self)
Packit e8bc57
{
Packit e8bc57
    xfree(self);
Packit e8bc57
}
Packit e8bc57
Packit e8bc57
int buff_fgetsln(buff_t *self, FILE *in, uint maxlen)
Packit e8bc57
{
Packit e8bc57
    uint readpos = self->t.leng;
Packit e8bc57
    int readcnt = xfgetsl((char *)self->t.u.text + readpos,
Packit e8bc57
	    min(self->size - readpos, maxlen), in, true);
Packit e8bc57
    /* WARNING: do not add NUL termination, the size must be exact! */
Packit e8bc57
    self->read = readpos;
Packit e8bc57
    if (readcnt >= 0)
Packit e8bc57
	self->t.leng += readcnt;
Packit e8bc57
    return readcnt;
Packit e8bc57
}
Packit e8bc57
Packit e8bc57
int buff_add(buff_t *self, word_t *in)
Packit e8bc57
{
Packit e8bc57
    uint readpos = self->t.leng;
Packit e8bc57
    int readcnt = in->leng;
Packit e8bc57
    uint new_size = self->t.leng + in->leng;
Packit e8bc57
    if (new_size > self->size) {
Packit e8bc57
	self->t.u.text = (byte *)xrealloc(self->t.u.text, new_size + D);
Packit e8bc57
	self->size = new_size;
Packit e8bc57
    }
Packit e8bc57
    self->read = readpos;
Packit e8bc57
    self->t.leng += readcnt;
Packit e8bc57
    memcpy(self->t.u.text + readpos, in->u.text, readcnt);
Packit e8bc57
    Z(self->t.u.text[self->t.leng]);		/* for easier debugging - removable */
Packit e8bc57
Packit e8bc57
    return readcnt;
Packit e8bc57
}
Packit e8bc57
Packit e8bc57
void buff_puts(const buff_t *self, uint width, FILE *fp)
Packit e8bc57
{
Packit e8bc57
    word_t word;
Packit e8bc57
    word.leng = self->t.leng - self->read;
Packit e8bc57
    word.u.text = self->t.u.text + self->read;
Packit e8bc57
    word_puts(&word, width, fp);
Packit e8bc57
}
Packit e8bc57
Packit e8bc57
void buff_shift(buff_t *self, uint start, uint length)
Packit e8bc57
{
Packit e8bc57
    /* Shift buffer contents to delete the specified segment. */
Packit e8bc57
    /* Implemented for deleting html comments.		      */
Packit e8bc57
Packit e8bc57
    BOGO_ASSERT(start + length <= self->t.leng,
Packit e8bc57
		"Invalid buff_shift() parameters.");
Packit e8bc57
Packit e8bc57
    memmove(self->t.u.text + start, self->t.u.text + start + length, self->t.leng - length);
Packit e8bc57
    self->t.leng -= length;
Packit e8bc57
    Z(self->t.u.text[self->t.leng]);		/* for easier debugging - removable */
Packit e8bc57
    return;
Packit e8bc57
}