/*************************************************************************** * Copyright (C) 07/2007 by Olaf Rempel * * razzor@kopf-tisch.de * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; version 2 of the License * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include #include #include #include #include #include "linebuffer.h" #define MIN(a,b) (((a) < (b)) ? (a) : (b)) struct linebuffer * create_linebuffer(int size) { struct linebuffer *buf = malloc(sizeof(struct linebuffer)); if (buf == NULL) return NULL; buf->size = size; buf->data = malloc(buf->size); if (buf->data == NULL) { free(buf); return NULL; } buf->pos = 0; return buf; } void linebuffer_free(struct linebuffer *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); buf->pos += 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 -1; 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 (tmp[i] == 0x08 && buf->pos > 0) { buf->pos--; /* copy */ } else if (tmp[i] >= ' ' || tmp[i] == '\n') { *(buf->data + buf->pos++) = tmp[i]; } if (buf->pos > buf->size) return -1; } return 0; } int linebuffer_writefd(struct linebuffer *buf, int fd) { int len = write(fd, buf->data, buf->pos); if (len <= 0) return -1; /* TODO: now assuming everything is written */ buf->pos = 0; return len; } int linebuffer_vprintf(struct linebuffer *buf, const char *fmt, va_list az) { int len = vsnprintf(buf->data + buf->pos, buf->size - buf->pos, fmt, az); if (len < 0 || len >= (buf->size - buf->pos)) return -1; buf->pos += len; return len; } int linebuffer_printf(struct linebuffer *buf, const char *fmt, ...) { va_list az; va_start(az, fmt); int ret = linebuffer_vprintf(buf, fmt, az); va_end(az); return ret; } char * linebuffer_getline(struct linebuffer *buf, int *len) { buf->newline = memchr(buf->data, '\n', buf->pos); if (buf->newline == NULL) return NULL; *(buf->newline) = '\0'; if (len != NULL) *len = buf->newline - buf->data; return buf->data; } int linebuffer_freeline(struct linebuffer *buf) { buf->pos -= (buf->newline - buf->data) +1; memmove(buf->data, buf->newline +1, buf->pos); buf->newline = NULL; return buf->pos; }