Back to index

libcitadel  8.12
Functions
FileIO; Prefer @ref StrBuf_BufferedIO
Stringbuffer, A class for manipulating strings with dynamic buffers

Slow I/O; avoid. More...

Collaboration diagram for FileIO; Prefer @ref StrBuf_BufferedIO:

Functions

eReadState StrBufChunkSipLine (StrBuf *LineBuf, IOBuffer *FB)
 extract a "next line" from Buf; Ptr to persist across several iterations
int StrBufTCP_read_line (StrBuf *buf, int *fd, int append, const char **Error)
 Read a line from socket flushes and closes the FD on error.
int StrBufReadBLOB (StrBuf *Buf, int *fd, int append, long nBytes, const char **Error)
 Input binary data from socket flushes and closes the FD on error.
int StrBufSipLine (StrBuf *LineBuf, const StrBuf *Buf, const char **Ptr)
 extract a "next line" from Buf; Ptr to persist across several iterations
void StrBufStripSlashes (StrBuf *Dir, int RemoveTrailingSlash)
 removes double slashes from pathnames

Detailed Description

Slow I/O; avoid.


Function Documentation

eReadState StrBufChunkSipLine ( StrBuf LineBuf,
IOBuffer FB 
)

extract a "next line" from Buf; Ptr to persist across several iterations

Parameters:
LineBufyour line will be copied here.
FBBLOB with lines of text...
Ptrmoved arround to keep the next-line across several iterations has to be &NULL on start; will be &NotNULL on end of buffer
Returns:
size of copied buffer

Definition at line 3779 of file stringbuf.c.

{
       const char *aptr, *ptr, *eptr;
       char *optr, *xptr;

       if ((FB == NULL) || (LineBuf == NULL) || (LineBuf->buf == NULL))
              return eReadFail;
       

       if ((FB->Buf == NULL) || (FB->ReadWritePointer == StrBufNOTNULL)) {
              FB->ReadWritePointer = StrBufNOTNULL;
              return eReadFail;
       }

       FlushStrBuf(LineBuf);
       if (FB->ReadWritePointer == NULL)
              ptr = aptr = FB->Buf->buf;
       else
              ptr = aptr = FB->ReadWritePointer;

       optr = LineBuf->buf;
       eptr = FB->Buf->buf + FB->Buf->BufUsed;
       xptr = LineBuf->buf + LineBuf->BufSize - 1;

       while ((ptr <= eptr) && 
              (*ptr != '\n') &&
              (*ptr != '\r') )
       {
              *optr = *ptr;
              optr++; ptr++;
              if (optr == xptr) {
                     LineBuf->BufUsed = optr - LineBuf->buf;
                     IncreaseBuf(LineBuf,  1, LineBuf->BufUsed + 1);
                     optr = LineBuf->buf + LineBuf->BufUsed;
                     xptr = LineBuf->buf + LineBuf->BufSize - 1;
              }
       }

       if (ptr >= eptr) {
              if (optr > LineBuf->buf)
                     optr --;
              if ((*(ptr - 1) != '\r') && (*(ptr - 1) != '\n')) {
                     LineBuf->BufUsed = optr - LineBuf->buf;
                     *optr = '\0';
                     if ((FB->ReadWritePointer != NULL) && 
                         (FB->ReadWritePointer != FB->Buf->buf))
                     {
                            /* Ok, the client application read all the data 
                               it was interested in so far. Since there is more to read, 
                               we now shrink the buffer, and move the rest over.
                            */
                            StrBufCutLeft(FB->Buf, 
                                         FB->ReadWritePointer - FB->Buf->buf);
                            FB->ReadWritePointer = FB->Buf->buf;
                     }
                     return eMustReadMore;
              }
       }
       LineBuf->BufUsed = optr - LineBuf->buf;
       *optr = '\0';       
       if ((ptr <= eptr) && (*ptr == '\r'))
              ptr ++;
       if ((ptr <= eptr) && (*ptr == '\n'))
              ptr ++;
       
       if (ptr < eptr) {
              FB->ReadWritePointer = ptr;
       }
       else {
              FlushStrBuf(FB->Buf);
              FB->ReadWritePointer = NULL;
       }

       return eReadSuccess;
}

Here is the call graph for this function:

int StrBufReadBLOB ( StrBuf Buf,
int *  fd,
int  append,
long  nBytes,
const char **  Error 
)

Input binary data from socket flushes and closes the FD on error.

Parameters:
Bufthe buffer to get the input to
fdpointer to the filedescriptor to read
appendAppend to an existing string or replace?
nBytesthe maximal number of bytes to read
Errorstrerror() on error
Returns:
numbers of chars read

Definition at line 4529 of file stringbuf.c.

{
       int fdflags;
       int rlen;
       int nSuccessLess;
       int nRead = 0;
       char *ptr;
       int IsNonBlock;
       struct timeval tv;
       fd_set rfds;

       if ((Buf == NULL) || (Buf->buf == NULL) || (*fd == -1))
       {
              *Error = ErrRBLF_BLOBPreConditionFailed;
              return -1;
       }
       if (!append)
              FlushStrBuf(Buf);
       if (Buf->BufUsed + nBytes >= Buf->BufSize)
              IncreaseBuf(Buf, 1, Buf->BufUsed + nBytes);

       ptr = Buf->buf + Buf->BufUsed;

       fdflags = fcntl(*fd, F_GETFL);
       IsNonBlock = (fdflags & O_NONBLOCK) == O_NONBLOCK;
       nSuccessLess = 0;
       while ((nRead < nBytes) && 
              (*fd != -1)) 
       {
              if (IsNonBlock)
              {
                     tv.tv_sec = 1;
                     tv.tv_usec = 0;
              
                     FD_ZERO(&rfds);
                     FD_SET(*fd, &rfds);
                     if (select(*fd + 1, &rfds, NULL, NULL, &tv) == -1) {
                            *Error = strerror(errno);
                            close (*fd);
                            *fd = -1;
                            if (*Error == NULL)
                                   *Error = ErrRBLF_SelectFailed;
                            return -1;
                     }
                     if (! FD_ISSET(*fd, &rfds) != 0) {
                            nSuccessLess ++;
                            continue;
                     }
              }

                if ((rlen = read(*fd, 
                             ptr,
                             nBytes - nRead)) == -1) {
                     close(*fd);
                     *fd = -1;
                     *Error = strerror(errno);
                        return rlen;
                }
              nRead += rlen;
              ptr += rlen;
              Buf->BufUsed += rlen;
       }
       Buf->buf[Buf->BufUsed] = '\0';
       return nRead;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int StrBufSipLine ( StrBuf LineBuf,
const StrBuf Buf,
const char **  Ptr 
)

extract a "next line" from Buf; Ptr to persist across several iterations

Parameters:
LineBufyour line will be copied here.
BufBLOB with lines of text...
Ptrmoved arround to keep the next-line across several iterations has to be &NULL on start; will be &NotNULL on end of buffer
Returns:
size of remaining buffer

Definition at line 4774 of file stringbuf.c.

{
       const char *aptr, *ptr, *eptr;
       char *optr, *xptr;

       if ((Buf == NULL) ||
           (*Ptr == StrBufNOTNULL) ||
           (LineBuf == NULL)||
           (LineBuf->buf == NULL))
       {
              *Ptr = StrBufNOTNULL;
              return 0;
       }

       FlushStrBuf(LineBuf);
       if (*Ptr==NULL)
              ptr = aptr = Buf->buf;
       else
              ptr = aptr = *Ptr;

       optr = LineBuf->buf;
       eptr = Buf->buf + Buf->BufUsed;
       xptr = LineBuf->buf + LineBuf->BufSize - 1;

       while ((ptr <= eptr) && 
              (*ptr != '\n') &&
              (*ptr != '\r') )
       {
              *optr = *ptr;
              optr++; ptr++;
              if (optr == xptr) {
                     LineBuf->BufUsed = optr - LineBuf->buf;
                     IncreaseBuf(LineBuf,  1, LineBuf->BufUsed + 1);
                     optr = LineBuf->buf + LineBuf->BufUsed;
                     xptr = LineBuf->buf + LineBuf->BufSize - 1;
              }
       }

       if ((ptr >= eptr) && (optr > LineBuf->buf))
              optr --;
       LineBuf->BufUsed = optr - LineBuf->buf;
       *optr = '\0';       
       if ((ptr <= eptr) && (*ptr == '\r'))
              ptr ++;
       if ((ptr <= eptr) && (*ptr == '\n'))
              ptr ++;
       
       if (ptr < eptr) {
              *Ptr = ptr;
       }
       else {
              *Ptr = StrBufNOTNULL;
       }

       return Buf->BufUsed - (ptr - Buf->buf);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void StrBufStripSlashes ( StrBuf Dir,
int  RemoveTrailingSlash 
)

removes double slashes from pathnames

Parameters:
Dirdirectory string to filter
RemoveTrailingSlashallows / disallows trailing slashes

Definition at line 4838 of file stringbuf.c.

{
       char *a, *b;

       a = b = Dir->buf;

       while (!IsEmptyStr(a)) {
              if (*a == '/') {
                     while (*a == '/')
                            a++;
                     *b = '/';
                     b++;
              }
              else {
                     *b = *a;
                     b++; a++;
              }
       }
       if ((RemoveTrailingSlash) &&
           (b > Dir->buf) && 
           (*(b - 1) == '/')){
              b--;
       }
       *b = '\0';
       Dir->BufUsed = b - Dir->buf;
}
int StrBufTCP_read_line ( StrBuf buf,
int *  fd,
int  append,
const char **  Error 
)

Read a line from socket flushes and closes the FD on error.

Parameters:
bufthe buffer to get the input to
fdpointer to the filedescriptor to read
appendAppend to an existing string or replace?
Errorstrerror() on error
Returns:
numbers of chars read

Definition at line 4188 of file stringbuf.c.

{
       int len, rlen, slen;

       if ((buf == NULL) || (buf->buf == NULL)) {
              *Error = strerror(EINVAL);
              return -1;
       }

       if (!append)
              FlushStrBuf(buf);

       slen = len = buf->BufUsed;
       while (1) {
              rlen = read(*fd, &buf->buf[len], 1);
              if (rlen < 1) {
                     *Error = strerror(errno);
                     
                     close(*fd);
                     *fd = -1;
                     
                     return -1;
              }
              if (buf->buf[len] == '\n')
                     break;
              if (buf->buf[len] != '\r')
                     len ++;
              if (len + 2 >= buf->BufSize) {
                     buf->BufUsed = len;
                     buf->buf[len+1] = '\0';
                     IncreaseBuf(buf, 1, -1);
              }
       }
       buf->BufUsed = len;
       buf->buf[len] = '\0';
       return len - slen;
}

Here is the call graph for this function:

Here is the caller graph for this function: