|
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 |
}
|