/* buffer/ph_buffer.c. Generated from buffer.c.in by configure. */ /* ** Copyright 1998-2004 University of Illinois Board of Trustees ** Copyright 1998-2004 Mark D. Roth ** All rights reserved. ** ** ph_buffer.c - network line buffer code ** ** Mark D. Roth ** Campus Information Technologies and Educational Services ** University of Illinois at Urbana-Champaign */ #include #include #include #include #include #ifdef STDC_HEADERS # include #endif struct ph_buffer { char *b_buf; size_t b_bufsize; char *b_readp; char *b_writep; ph_read_func_t b_readfunc; void *b_app_data; }; int ph_buffer_new(ph_buffer_t *bufp, size_t bufsize, ph_read_func_t readfunc, void *app_data) { *bufp = (ph_buffer_t)calloc(1, sizeof(struct ph_buffer)); if (*bufp == NULL) return -1; (*bufp)->b_buf = (char *)calloc(1, bufsize); if ((*bufp)->b_buf == NULL) return -1; (*bufp)->b_readp = (*bufp)->b_writep = (*bufp)->b_buf; (*bufp)->b_bufsize = bufsize; (*bufp)->b_readfunc = readfunc; (*bufp)->b_app_data = app_data; return 0; } #define BUF_FREE_LEN(buf) \ (((buf)->b_bufsize - 1) - ((buf)->b_writep - (buf)->b_buf)) ssize_t ph_buffer_read_line(ph_buffer_t buf, char *callbuf, size_t callbuflen) { char *linep; ssize_t sz; size_t retlen; /* keep reading until we have a line in the buffer */ while (strchr(buf->b_readp, '\n') == NULL) { sz = (*(buf->b_readfunc))(buf->b_app_data, buf->b_writep, BUF_FREE_LEN(buf)); if (sz == 0) { errno = ECONNRESET; return -1; } if (sz == (ssize_t)-1) return -1; buf->b_writep += sz; *(buf->b_writep) = '\0'; } /* chop off the first line and move read pointer */ linep = strsep(&(buf->b_readp), "\n"); /* copy line to caller-suppied buffer */ retlen = strlcpy(callbuf, linep, callbuflen); /* move remaining data to beginning of buffer and update pointers */ sz = buf->b_writep - buf->b_readp; memmove(buf->b_buf, buf->b_readp, sz + 1); buf->b_writep = buf->b_buf + sz; buf->b_readp = buf->b_buf; return retlen; } void ph_free(ph_buffer_t buf) { if (buf->b_buf != NULL) free(buf->b_buf); free(buf); }