linebuffer update

This commit is contained in:
Olaf Rempel 2007-06-19 15:20:31 +02:00
parent 503b837763
commit 6d76ec29ec
3 changed files with 94 additions and 39 deletions

View File

@ -52,7 +52,7 @@ static int data_cb(int fd, void *privdata)
{ {
struct client_con *con = (struct client_con *)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)); log_print(LOG_WARN, "data_cb(): client %s read", get_sockaddr_buf(&con->addr));
list_del(&con->list); list_del(&con->list);
free_client(con); free_client(con);
@ -60,7 +60,7 @@ static int data_cb(int fd, void *privdata)
} }
char *line; char *line;
while ((line = linebuffer_get(con->lbuf)) != NULL) { while ((line = linebuffer_getline(con->lbuf, NULL)) != NULL) {
if (strncmp(line, "CTBW ", 5) == 0) { if (strncmp(line, "CTBW ", 5) == 0) {
int bwup, bwdn, liup, lidn; int bwup, bwdn, liup, lidn;
if (sscanf(line +5, "%d,%d %d,%d", &bwdn, &bwup, &lidn, &liup) == 4) { 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; con->chunk_avail = chunk3;
} }
} }
free(line); linebuffer_freeline(con->lbuf);
} }
return 0; return 0;
} }

View File

@ -2,67 +2,115 @@
#include <stdlib.h> #include <stdlib.h>
#include <unistd.h> #include <unistd.h>
#include <string.h> #include <string.h>
#include <stdarg.h>
#include "linebuffer.h" #include "linebuffer.h"
#define MIN(a,b) (((a) < (b)) ? (a) : (b))
struct linebuffer * create_linebuffer(int size) struct linebuffer * create_linebuffer(int size)
{ {
struct linebuffer *retval = malloc(sizeof(struct linebuffer) + size); struct linebuffer *buf = malloc(sizeof(struct linebuffer));
if (retval == NULL) if (buf == NULL)
return NULL; return NULL;
retval->size = size; buf->size = size;
retval->pos = 0; buf->data = malloc(buf->size);
return retval; 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]; free(buf->data);
int len = read(fd, buf, sizeof(buf)); 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) if (len <= 0)
return -1; return -1;
int i; int i;
for (i = 0; i < len; i++) { for (i = 0; i < len; i++) {
/* "understand" backspace */ /* "understand" backspace */
if (buf[i] == 0x08 && lbuf->pos > 0) { if (tmp[i] == 0x08 && buf->pos > 0) {
lbuf->pos--; buf->pos--;
/* copy */ /* copy */
} else if (buf[i] >= ' ' || buf[i] == '\n') { } else if (tmp[i] >= ' ' || tmp[i] == '\n') {
lbuf->data[lbuf->pos++] = buf[i]; *(buf->data + buf->pos++) = tmp[i];
} }
if (lbuf->pos > lbuf->size) if (buf->pos > buf->size)
return -1; return -1;
} }
return 0; 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); va_list az;
if (newline == NULL) 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; return NULL;
char *retval = NULL; *(buf->newline) = '\0';
*newline = '\0';
int len = newline - lbuf->data; if (len != NULL)
if (len > 0) *len = buf->newline - buf->data;
retval = strdup(lbuf->data);
lbuf->pos -= len +1; return buf->data;
memmove(lbuf->data, newline +1, lbuf->pos);
return retval;
} }
int linebuffer_clear(struct linebuffer *lbuf) int linebuffer_freeline(struct linebuffer *buf)
{ {
int oldpos = lbuf->pos; buf->pos -= (buf->newline - buf->data) +1;
lbuf->pos = 0; memmove(buf->data, buf->newline +1, buf->pos);
return oldpos; buf->newline = NULL;
return buf->pos;
} }

View File

@ -2,17 +2,24 @@
#define _LINEBUFFER_H_ #define _LINEBUFFER_H_
struct linebuffer { struct linebuffer {
int size; unsigned int size;
int pos; unsigned int pos;
char data[0]; char *newline;
char *data;
}; };
struct linebuffer * create_linebuffer(int size); struct linebuffer * create_linebuffer(int size);
void linebuffer_free(struct linebuffer *buf);
int linebuffer_read(struct linebuffer *lbuf, int fd); int linebuffer_clear(struct linebuffer *buf);
char * linebuffer_get(struct linebuffer *lbuf);
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_ */ #endif /* _LINEBUFFER_H_ */