2007-07-14 15:42:56 +02:00
|
|
|
/***************************************************************************
|
|
|
|
* 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. *
|
|
|
|
***************************************************************************/
|
2007-07-07 17:24:03 +02:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <stdarg.h>
|
|
|
|
|
|
|
|
#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;
|
|
|
|
}
|