From: Wilfried Göesgens Date: Sat, 11 Apr 2009 16:31:25 +0000 (+0000) Subject: * add fast linebuffered function just cutting its buffer before it reads a new chunk... X-Git-Tag: v7.86~1282 X-Git-Url: https://code.citadel.org/?p=citadel.git;a=commitdiff_plain;h=3ae3f33dae5772d487b9e1fd225476c3bce5be81 * add fast linebuffered function just cutting its buffer before it reads a new chunk; this way we save lots of memmoves when reading large line arrays line by line. --- diff --git a/libcitadel/debian/changelog b/libcitadel/debian/changelog index 4fa753871..f2ba88a43 100644 --- a/libcitadel/debian/changelog +++ b/libcitadel/debian/changelog @@ -1,3 +1,9 @@ +libcitadel (7.50-73) unstable; urgency=low + + * release + + -- Wilfried Goesgens Tue, 17 Mar 2009 00:00:00 +0002 + libcitadel (7.43-72) unstable; urgency=low * Beta release diff --git a/libcitadel/debian/control b/libcitadel/debian/control index f0168ebd3..d35afe461 100644 --- a/libcitadel/debian/control +++ b/libcitadel/debian/control @@ -16,7 +16,7 @@ Description: Citadel toolbox Package: libcitadel2-dbg Section: libdevel Architecture: any -Depends: ${shlibs:Depends}, libcitadel2 (= ${binary:Version}) +Depends: ${shlibs:Depends}, libcitadel2 Description: Debugging symbols for libcitadel2 This library contains the commonly used routines for the citadel suite. . diff --git a/libcitadel/lib/libcitadel.h b/libcitadel/lib/libcitadel.h index cffb7bfbb..59364fdcc 100644 --- a/libcitadel/lib/libcitadel.h +++ b/libcitadel/lib/libcitadel.h @@ -241,6 +241,13 @@ int StrBufTCP_read_buffered_line(StrBuf *Line, int timeout, int selectresolution, const char **Error); +int StrBufTCP_read_buffered_line_fast(StrBuf *Line, + StrBuf *buf, + const char **Pos, + int *fd, + int timeout, + int selectresolution, + const char **Error); int StrBufSipLine(StrBuf *LineBuf, StrBuf *Buf, const char **Ptr); int StrBufExtract_token(StrBuf *dest, const StrBuf *Source, int parmnum, char separator); diff --git a/libcitadel/lib/stringbuf.c b/libcitadel/lib/stringbuf.c index f64ae13b0..d2b2f7d8a 100644 --- a/libcitadel/lib/stringbuf.c +++ b/libcitadel/lib/stringbuf.c @@ -1350,6 +1350,107 @@ int StrBufTCP_read_buffered_line(StrBuf *Line, } +/** + * \brief Read a line from socket + * flushes and closes the FD on error + * \param buf the buffer to get the input to + * \param Pos pointer to the current read position, should be NULL initialized! + * \param fd pointer to the filedescriptor to read + * \param append Append to an existing string or replace? + * \param Error strerror() on error + * \returns numbers of chars read + */ +int StrBufTCP_read_buffered_line_fast(StrBuf *Line, + StrBuf *buf, + const char **Pos, + int *fd, + int timeout, + int selectresolution, + const char **Error) +{ + int len, rlen; + int nSuccessLess = 0; + fd_set rfds; + const char *pch = NULL; + int fdflags; + struct timeval tv; + + if ((buf->BufUsed > 0) && (Pos != NULL)) { + if (*Pos == NULL) + *Pos = buf->buf; + pch = strchr(*Pos, '\n'); + if (pch != NULL) { + rlen = 0; + len = pch - *Pos; + if (len > 0 && (*(pch - 1) == '\r') ) + rlen ++; + StrBufSub(Line, buf, (*Pos - buf->buf), len - rlen); + *Pos = pch + 1; + return len - rlen; + } + } + + if (*Pos != NULL) { + StrBufCutLeft(buf, (*Pos - buf->buf)); + *Pos = NULL; + } + + if (buf->BufSize - buf->BufUsed < 10) + IncreaseBuf(buf, 1, -1); + + fdflags = fcntl(*fd, F_GETFL); + if ((fdflags & O_NONBLOCK) == O_NONBLOCK) + return -1; + + while ((nSuccessLess < timeout) && (pch == NULL)) { + tv.tv_sec = selectresolution; + tv.tv_usec = 0; + + FD_ZERO(&rfds); + FD_SET(*fd, &rfds); + if (select(*fd + 1, NULL, &rfds, NULL, &tv) == -1) { + *Error = strerror(errno); + close (*fd); + *fd = -1; + return -1; + } + if (FD_ISSET(*fd, &rfds)) { + rlen = read(*fd, + &buf->buf[buf->BufUsed], + buf->BufSize - buf->BufUsed - 1); + if (rlen < 1) { + *Error = strerror(errno); + close(*fd); + *fd = -1; + return -1; + } + else if (rlen > 0) { + nSuccessLess = 0; + buf->BufUsed += rlen; + buf->buf[buf->BufUsed] = '\0'; + if (buf->BufUsed + 10 > buf->BufSize) { + IncreaseBuf(buf, 1, -1); + } + pch = strchr(buf->buf, '\n'); + continue; + } + } + nSuccessLess ++; + } + if (pch != NULL) { + *Pos = buf->buf; + rlen = 0; + len = pch - *Pos; + if (len > 0 && (*(pch - 1) == '\r') ) + rlen ++; + StrBufSub(Line, buf, 0, len - rlen); + *Pos = *Pos + len + 1; + return len - rlen; + } + return -1; + +} + /** * \brief Input binary data from socket * flushes and closes the FD on error