/** * @PROJECT CGI Bash Shell Interface * @COPYRIGHT See COPYING in the top level directory * @FILE buffer.c * @PURPOSE CBSI Buffers * @DEVELOPERS Nathan Angelacos * Rafal Kupiec */ #include #include #include #include #include #include #include #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); }