#include #include #include #include #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; }