127 líneas
2.7 KiB
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);
|
|
}
|