#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include "line.h"
#include "buffer.h"
#include "misc.h"
static buffer_t *buffer_alloc(void);
buffer_t *buffer_alloc(void)
{
int ret = 0;
buffer_t *b = NULL;
b = (buffer_t *)malloc(sizeof(buffer_t));
if (b == NULL)
return NULL;
memset((buffer_t *)b, 0, sizeof(buffer_t));
b->l = line_alloc();
if (b->l == NULL) {
free(b);
return NULL;
}
ret = line_init(b->l, NULL, 0);
if (!ret) {
line_kill(b->l);
free(b);
return NULL;
}
return b;
}
buffer_t *buffer_init(int fd, unsigned long blen)
{
buffer_t *b = NULL;
/*
Need at least 2 bytes
*/
if (blen < 2)
return NULL;
b = buffer_alloc();
if (b == NULL)
return NULL;
b->b = (char *)malloc(blen + 1);
if (b->b == NULL) {
buffer_kill(b);
return NULL;
}
b->fd = fd;
b->blen = blen;
memset((char *)b->b, 0, blen + 1);
return b;
}
void buffer_restart(buffer_t *b, int fd)
{
b->fd = fd;
b->eof = 0;
b->cin = 0;
b->restart = 0;
b->ulen = 0;
b->clen = 0;
b->fbrk = 0;
line_restart(b->l);
if (b->fd == -1)
b->bp = b->b;
else {
b->bp = NULL;
memset((char *)b->b, 0, b->blen);
}
}
void buffer_kill(buffer_t *b)
{
if (b->l)
line_kill(b->l);
if ((b->b) && (b->fd != -1))
free(b->b);
free(b);
}
char *buffer_next_line(buffer_t *bb)
{
int ret = 0;
char *p = NULL, *t = NULL, *bp = NULL, fn = 0;
if (bb->eof)
return NULL;
if (bb->lbp != bb->bp)
bb->lbp = bb->bp;
/*
Call line_restart?
*/
if (bb->restart) {
line_restart(bb->l);
bb->restart = 0;
}
/*
Buffer is empty
*/
if (bb->cin == 0) {
if (bb->fd != -1) {
ret = read(bb->fd, bb->b, (bb->blen - 1));
if (!ret) {
bb->eof = 1;
return NULL;
}
else
bb->cin = ret;
}
else {
bb->eof = 1;
return NULL;
}
}
while(1) {
fn = 0;
if (bb->fd == -1)
bp = p = t = bb->bp;
else
bp = p = t = bb->b;
for (bb->clen = bb->ulen = 0;; p++) {
if (*p == '\0') {
p = NULL;
break;
}
else if (*p == '\n') {
// XXX Patch Submitted
if (bb->ulen) {
if (*(p - 1) == '\r')
bb->ulen--;
}
fn = 1;
bb->clen++;
break;
}
else {
bb->ulen++;
bb->clen++;
}
}
/*
No newline found.
*/
if (!fn) {
ret = line_inject(bb->l, bp, bb->ulen);
if (!ret)
return NULL;
if (bb->fd == -1)
bb->bp += bb->clen;
bb->fn = 1;
bb->cin = 0;
bb->restart = 0;
bb->ulen = 0;
bb->clen = 0;
if (bb->fd != -1)
memset((char *)bb->b, 0, bb->blen);
return buffer_next_line(bb);
}
if (bb->ulen) {
ret = line_inject(bb->l, bp, bb->ulen);
if (!ret)
return NULL;
}
bb->restart = 1;
if (bb->fd != -1)
#if 0
memcpy((char *)bb->b, (char *)(bb->b + bb->clen), (bb->blen - bb->clen));
#endif
memmove((char *)bb->b, (char *)(bb->b + bb->clen), (bb->blen - bb->clen));
else
bb->bp += bb->clen;
bb->cin -= bb->clen;
if (bb->fd != -1)
memset((char *)(bb->b + bb->cin + 1), 0, (bb->blen - bb->cin));
bb->ulen = 0;
bb->clen = 0;
return bb->l->data;
}
return NULL;
}
syntax highlighted by Code2HTML, v. 0.9.1