cbsi/buffer.c

127 líneas
2.7 KiB
C

/**
* @PROJECT CGI Bash Shell Interface
* @COPYRIGHT See COPYING in the top level directory
* @FILE buffer.c
* @PURPOSE CBSI Buffers
* @DEVELOPERS Nathan Angelacos <nangel@users.sourceforge.net>
* Rafal Kupiec <belliash@asiotec.eu.org>
*/
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include "buffer.h"
void buffer_add(buffer_t* buf, const void* data, unsigned long size) {
unsigned long newsize;
unsigned long index;
if((buf->ptr + size) >= buf->limit) {
index = (buf->limit - buf->data);
newsize = index;
while(newsize <= index + size) {
newsize += 1024;
}
index = buf->ptr - buf->data;
buf->data = realloc(buf->data, newsize);
buf->limit = buf->data + newsize;
buf->ptr = buf->data + index;
}
memcpy(buf->ptr, data, size);
buf->ptr += size;
}
void buffer_destroy(buffer_t* buf) {
if(buf->data) {
free(buf->data);
}
buffer_init(buf);
}
void buffer_init(buffer_t* buf) {
buf->data = NULL;
buf->ptr = NULL;
buf->limit = NULL;
}
void buffer_reset(buffer_t* buf) {
if(buf->data) {
buf->ptr = buf->data;
} else {
buf->ptr = NULL;
}
}
void sbuffer_destroy(sbuffer_t* sbuf) {
free(sbuf->buf);
}
int sbuffer_init(sbuffer_t* sbuf, int size) {
sbuf->maxsize = size;
sbuf->buf = malloc (sbuf->maxsize);
sbuf->maxsize -= 1;
sbuf->fh = 0;
sbuf->eof = 0;
sbuf->len = 0;
sbuf->ptr = sbuf->buf;
sbuf->bufsize = 0;
sbuf->maxread = 0;
sbuf->nrread = 0;
return (sbuf->buf != NULL);
}
int sbuffer_read(sbuffer_t* sbuf, char* matchstr) {
int len, pos;
int r;
if((sbuf->eof) && (sbuf->ptr > sbuf->buf)) {
return 0;
}
if((sbuf->bufsize == 0) || (sbuf->ptr >= (sbuf->buf + sbuf->bufsize - strlen (matchstr)))) {
len = sbuf->bufsize - (sbuf->ptr - sbuf->buf);
if(len) {
memmove(sbuf->buf, sbuf->ptr, len);
}
sbuf->ptr = sbuf->buf;
sbuf->bufsize = len;
if(fcntl(sbuf->fh, F_GETFL) == -1) {
r = 0;
} else {
size_t n = sbuf->maxsize - len;
if(sbuf->maxread && sbuf->maxread < sbuf->nrread + n) {
n = sbuf->maxread - sbuf->nrread;
}
r = read(sbuf->fh, sbuf->buf + len, n);
}
if(r == 0 || (r < 0 && errno != EINTR)) {
sbuf->eof = -1;
} else {
sbuf->bufsize += (r > 0) ? r : 0;
sbuf->nrread += (r > 0) ? r : 0;
}
}
pos = 0;
len = sbuf->bufsize - (int) (sbuf->ptr - sbuf->buf) - strlen(matchstr);
while(memcmp(matchstr, sbuf->ptr + pos, strlen(matchstr)) && (pos < len)) {
pos++;
}
if(pos < len) {
sbuf->len = pos;
sbuf->segment = sbuf->ptr;
sbuf->ptr = sbuf->segment + pos + strlen(matchstr);
return -1;
}
if(sbuf->eof) {
len += strlen(matchstr);
}
sbuf->segment = sbuf->ptr;
sbuf->len = len;
sbuf->ptr += sbuf->len;
return (sbuf->eof) ? (-1) : (0);
}