From 6d76ec29ec2468175a8523e30ca5f9d2d2c1163f Mon Sep 17 00:00:00 2001 From: Olaf Rempel Date: Tue, 19 Jun 2007 15:20:31 +0200 Subject: [PATCH] linebuffer update --- connection.c | 6 +-- linebuffer.c | 108 +++++++++++++++++++++++++++++++++++++-------------- linebuffer.h | 19 ++++++--- 3 files changed, 94 insertions(+), 39 deletions(-) diff --git a/connection.c b/connection.c index ede9aad..c6d2f53 100644 --- a/connection.c +++ b/connection.c @@ -52,7 +52,7 @@ static int data_cb(int fd, void *privdata) { struct client_con *con = (struct client_con *)privdata; - if (linebuffer_read(con->lbuf, fd) < 0) { + if (linebuffer_readfd(con->lbuf, fd) < 0) { log_print(LOG_WARN, "data_cb(): client %s read", get_sockaddr_buf(&con->addr)); list_del(&con->list); free_client(con); @@ -60,7 +60,7 @@ static int data_cb(int fd, void *privdata) } char *line; - while ((line = linebuffer_get(con->lbuf)) != NULL) { + while ((line = linebuffer_getline(con->lbuf, NULL)) != NULL) { if (strncmp(line, "CTBW ", 5) == 0) { int bwup, bwdn, liup, lidn; if (sscanf(line +5, "%d,%d %d,%d", &bwdn, &bwup, &lidn, &liup) == 4) { @@ -87,7 +87,7 @@ static int data_cb(int fd, void *privdata) con->chunk_avail = chunk3; } } - free(line); + linebuffer_freeline(con->lbuf); } return 0; } diff --git a/linebuffer.c b/linebuffer.c index 88d13d6..b0a3eb7 100644 --- a/linebuffer.c +++ b/linebuffer.c @@ -2,67 +2,115 @@ #include #include #include +#include #include "linebuffer.h" +#define MIN(a,b) (((a) < (b)) ? (a) : (b)) + struct linebuffer * create_linebuffer(int size) { - struct linebuffer *retval = malloc(sizeof(struct linebuffer) + size); - if (retval == NULL) + struct linebuffer *buf = malloc(sizeof(struct linebuffer)); + if (buf == NULL) return NULL; - retval->size = size; - retval->pos = 0; - return retval; + buf->size = size; + buf->data = malloc(buf->size); + if (buf->data == NULL) { + free(buf); + return NULL; + } + + buf->pos = 0; + return buf; } -int linebuffer_read(struct linebuffer *lbuf, int fd) +void linebuffer_free(struct linebuffer *buf) { - char buf[32]; - int len = read(fd, buf, sizeof(buf)); + free(buf->data); + free(buf); +} + +int linebuffer_clear(struct linebuffer *buf) +{ + int oldpos = buf->pos; + buf->pos = 0; + return oldpos; +} + +int linebuffer_put(struct linebuffer *buf, const char *src, unsigned int size) +{ + int len = MIN(buf->size - buf->pos, size); + memcpy(buf->data + buf->pos, src, len); + return len; +} + +int linebuffer_readfd(struct linebuffer *buf, int fd) +{ + int len = read(fd, buf->data + buf->pos, buf->size - buf->pos); + if (len <= 0) + return len; + + buf->pos += len; + return len; +} + +int linebuffer_parsefd(struct linebuffer *buf, int fd) +{ + char tmp[32]; + int len = read(fd, tmp, sizeof(tmp)); if (len <= 0) return -1; int i; for (i = 0; i < len; i++) { /* "understand" backspace */ - if (buf[i] == 0x08 && lbuf->pos > 0) { - lbuf->pos--; + if (tmp[i] == 0x08 && buf->pos > 0) { + buf->pos--; /* copy */ - } else if (buf[i] >= ' ' || buf[i] == '\n') { - lbuf->data[lbuf->pos++] = buf[i]; + } else if (tmp[i] >= ' ' || tmp[i] == '\n') { + *(buf->data + buf->pos++) = tmp[i]; } - if (lbuf->pos > lbuf->size) + if (buf->pos > buf->size) return -1; } - return 0; } -char * linebuffer_get(struct linebuffer *lbuf) +int linebuffer_printf(struct linebuffer *buf, const char *fmt, ...) { - char *newline = memchr(lbuf->data, '\n', lbuf->pos); - if (newline == NULL) + va_list az; + va_start(az, fmt); + int len = vsnprintf(buf->data + buf->pos, buf->size - buf->pos, fmt, az); + va_end(az); + + if (len < 0 || len >= (buf->size - buf->pos)) + return -1; + + buf->pos += len; + return len; +} + +char * linebuffer_getline(struct linebuffer *buf, int *len) +{ + buf->newline = memchr(buf->data, '\n', buf->pos); + if (buf->newline == NULL) return NULL; - char *retval = NULL; - *newline = '\0'; + *(buf->newline) = '\0'; - int len = newline - lbuf->data; - if (len > 0) - retval = strdup(lbuf->data); + if (len != NULL) + *len = buf->newline - buf->data; - lbuf->pos -= len +1; - memmove(lbuf->data, newline +1, lbuf->pos); - - return retval; + return buf->data; } -int linebuffer_clear(struct linebuffer *lbuf) +int linebuffer_freeline(struct linebuffer *buf) { - int oldpos = lbuf->pos; - lbuf->pos = 0; - return oldpos; + buf->pos -= (buf->newline - buf->data) +1; + memmove(buf->data, buf->newline +1, buf->pos); + buf->newline = NULL; + return buf->pos; } diff --git a/linebuffer.h b/linebuffer.h index e9d2a77..de5a1b0 100644 --- a/linebuffer.h +++ b/linebuffer.h @@ -2,17 +2,24 @@ #define _LINEBUFFER_H_ struct linebuffer { - int size; - int pos; + unsigned int size; + unsigned int pos; - char data[0]; + char *newline; + char *data; }; struct linebuffer * create_linebuffer(int size); +void linebuffer_free(struct linebuffer *buf); -int linebuffer_read(struct linebuffer *lbuf, int fd); -char * linebuffer_get(struct linebuffer *lbuf); +int linebuffer_clear(struct linebuffer *buf); -int linebuffer_clear(struct linebuffer *lbuf); +int linebuffer_put(struct linebuffer *buf, const char *src, unsigned int size); +int linebuffer_readfd(struct linebuffer *buf, int fd); +int linebuffer_parsefd(struct linebuffer *buf, int fd); +int linebuffer_printf(struct linebuffer *buf, const char *fmt, ...); + +char * linebuffer_getline(struct linebuffer *buf, int *len); +int linebuffer_freeline(struct linebuffer *buf); #endif /* _LINEBUFFER_H_ */