]> code.citadel.org Git - citadel.git/blobdiff - libcitadel/lib/stringbuf.c
* remove temporary debian file
[citadel.git] / libcitadel / lib / stringbuf.c
index f669ecf362ae895a76d078358a58e8fb9fda6ad6..b7dc903c8e392394da2b604c9278727552098fad 100644 (file)
@@ -332,10 +332,10 @@ long StrBufPeek(StrBuf *Buf, const char* ptr, long nThChar, char PeekValue)
  */
 void StrBufAppendBuf(StrBuf *Buf, const StrBuf *AppendBuf, unsigned long Offset)
 {
-  if ((AppendBuf == NULL) || (Buf == NULL) || (AppendBuf->buf == NULL))
+       if ((AppendBuf == NULL) || (Buf == NULL) || (AppendBuf->buf == NULL))
                return;
 
-       if (Buf->BufSize - Offset < AppendBuf->BufUsed + Buf->BufUsed)
+       if (Buf->BufSize - Offset < AppendBuf->BufUsed + Buf->BufUsed + 1)
                IncreaseBuf(Buf, 
                            (Buf->BufUsed > 0), 
                            AppendBuf->BufUsed + Buf->BufUsed);
@@ -584,13 +584,13 @@ void StrMsgEscAppend(StrBuf *Target, StrBuf *Source, const char *PlainIn)
        if (len == 0) 
                return;
 
-       eptr = Target->buf + Target->BufSize - 6
+       eptr = Target->buf + Target->BufSize - 8
        tptr = Target->buf + Target->BufUsed;
        
        while (aptr < eiptr){
                if(tptr >= eptr) {
                        IncreaseBuf(Target, 1, -1);
-                       eptr = Target->buf + Target->BufSize - 6
+                       eptr = Target->buf + Target->BufSize - 8
                        tptr = Target->buf + Target->BufUsed;
                }
               
@@ -649,12 +649,12 @@ long StrECMAEscAppend(StrBuf *Target, const StrBuf *Source, const char *PlainIn)
                return -1;
 
        bptr = Target->buf + Target->BufUsed;
-       eptr = Target->buf + Target->BufSize - 2; /* our biggest unit to put in...  */
+       eptr = Target->buf + Target->BufSize - 3; /* our biggest unit to put in...  */
 
        while (aptr < eiptr){
                if(bptr >= eptr) {
                        IncreaseBuf(Target, 1, -1);
-                       eptr = Target->buf + Target->BufSize - 2
+                       eptr = Target->buf + Target->BufSize - 3
                        bptr = Target->buf + Target->BufUsed;
                }
                else if (*aptr == '"') {
@@ -697,7 +697,7 @@ int StrBufSub(StrBuf *dest, const StrBuf *Source, unsigned long Offset, size_t n
        }
        if (Offset + nChars < Source->BufUsed)
        {
-               if (nChars > dest->BufSize)
+               if (nChars >= dest->BufSize)
                        IncreaseBuf(dest, 0, nChars + 1);
                memcpy(dest->buf, Source->buf + Offset, nChars);
                dest->BufUsed = nChars;
@@ -705,7 +705,7 @@ int StrBufSub(StrBuf *dest, const StrBuf *Source, unsigned long Offset, size_t n
                return nChars;
        }
        NCharsRemain = Source->BufUsed - Offset;
-       if (NCharsRemain > dest->BufSize)
+       if (NCharsRemain  >= dest->BufSize)
                IncreaseBuf(dest, 0, NCharsRemain + 1);
        memcpy(dest->buf, Source->buf + Offset, NCharsRemain);
        dest->BufUsed = NCharsRemain;
@@ -936,6 +936,9 @@ int StrBufExtract_token(StrBuf *dest, const StrBuf *Source, int parmnum, char se
 }
 
 
+
+
+
 /**
  * \brief a string tokenizer to fetch an integer
  * \param dest Destination StringBuffer
@@ -952,6 +955,7 @@ int StrBufExtract_int(const StrBuf* Source, int parmnum, char separator)
        buf[0] = '\0';
        tmp.BufSize = 64;
        tmp.BufUsed = 0;
+       tmp.ConstBuf = 1;
        if (StrBufExtract_token(&tmp, Source, parmnum, separator) > 0)
                return(atoi(buf));
        else
@@ -974,6 +978,7 @@ long StrBufExtract_long(const StrBuf* Source, int parmnum, char separator)
        buf[0] = '\0';
        tmp.BufSize = 64;
        tmp.BufUsed = 0;
+       tmp.ConstBuf = 1;
        if (StrBufExtract_token(&tmp, Source, parmnum, separator) > 0)
                return(atoi(buf));
        else
@@ -998,6 +1003,7 @@ unsigned long StrBufExtract_unsigned_long(const StrBuf* Source, int parmnum, cha
        buf[0] = '\0';
        tmp.BufSize = 64;
        tmp.BufUsed = 0;
+       tmp.ConstBuf = 1;
        if (StrBufExtract_token(&tmp, Source, parmnum, separator) > 0) {
                pnum = &buf[0];
                if (*pnum == '-')
@@ -1010,6 +1016,207 @@ unsigned long StrBufExtract_unsigned_long(const StrBuf* Source, int parmnum, cha
 
 
 
+/**
+ * \brief a string tokenizer
+ * \param dest Destination StringBuffer
+ * \param Source StringBuffer to read into
+ * \param pStart pointer to the end of the last token. Feed with NULL.
+ * \param separator tokenizer param
+ * \returns -1 if not found, else length of token.
+ */
+int StrBufExtract_NextToken(StrBuf *dest, const StrBuf *Source, const char **pStart, char separator)
+{
+       const char *s, *EndBuffer;      //* source * /
+       int len = 0;                    //* running total length of extracted string * /
+       int current_token = 0;          //* token currently being processed * /
+        
+       if (dest != NULL) {
+               dest->buf[0] = '\0';
+               dest->BufUsed = 0;
+       }
+       else
+               return(-1);
+
+       if ((Source == NULL) || 
+           (Source->BufUsed ==0)) {
+               return(-1);
+       }
+       if (*pStart == NULL)
+               *pStart = Source->buf;
+
+       EndBuffer = Source->buf + Source->BufUsed;
+
+       if ((*pStart < Source->buf) || 
+           (*pStart >  EndBuffer)) {
+               return (-1);
+       }
+
+
+       s = *pStart;
+
+       //cit_backtrace();
+       //lprintf (CTDL_DEBUG, "test >: n: %d sep: %c source: %s \n willi \n", parmnum, separator, source);
+
+       while ((s<EndBuffer) && !IsEmptyStr(s)) {
+               if (*s == separator) {
+                       ++current_token;
+               }
+               if (len >= dest->BufSize)
+                       if (!IncreaseBuf(dest, 1, -1)) {
+                               *pStart = EndBuffer + 1;
+                               break;
+                       }
+               if ( (current_token == 0) && 
+                    (*s != separator)) {
+                       dest->buf[len] = *s;
+                       ++len;
+               }
+               else if (current_token > 0) {
+                       *pStart = s;
+                       break;
+               }
+               ++s;
+       }
+       *pStart = s;
+       (*pStart) ++;
+
+       dest->buf[len] = '\0';
+       dest->BufUsed = len;
+               //lprintf (CTDL_DEBUG,"test <!: %s\n", dest);
+       //lprintf (CTDL_DEBUG,"test <: %d; %s\n", len, dest);
+       return(len);
+}
+
+
+/**
+ * \brief a string tokenizer
+ * \param dest Destination StringBuffer
+ * \param Source StringBuffer to read into
+ * \param pStart pointer to the end of the last token. Feed with NULL.
+ * \param separator tokenizer param
+ * \returns -1 if not found, else length of token.
+ */
+int StrBufSkip_NTokenS(const StrBuf *Source, const char **pStart, char separator, int nTokens)
+{
+       const char *s, *EndBuffer;      //* source * /
+       int len = 0;                    //* running total length of extracted string * /
+       int current_token = 0;          //* token currently being processed * /
+
+       if ((Source == NULL) || 
+           (Source->BufUsed ==0)) {
+               return(-1);
+       }
+       if (nTokens == 0)
+               return Source->BufUsed;
+
+       if (*pStart == NULL)
+               *pStart = Source->buf;
+
+       EndBuffer = Source->buf + Source->BufUsed;
+
+       if ((*pStart < Source->buf) || 
+           (*pStart >  EndBuffer)) {
+               return (-1);
+       }
+
+
+       s = *pStart;
+
+       //cit_backtrace();
+       //lprintf (CTDL_DEBUG, "test >: n: %d sep: %c source: %s \n willi \n", parmnum, separator, source);
+
+       while ((s<EndBuffer) && !IsEmptyStr(s)) {
+               if (*s == separator) {
+                       ++current_token;
+               }
+               if (current_token >= nTokens) {
+                       break;
+               }
+               ++s;
+       }
+       *pStart = s;
+       (*pStart) ++;
+
+       return(len);
+}
+
+/**
+ * \brief a string tokenizer to fetch an integer
+ * \param dest Destination StringBuffer
+ * \param parmnum n'th parameter to extract
+ * \param separator tokenizer param
+ * \returns 0 if not found, else integer representation of the token
+ */
+int StrBufExtractNext_int(const StrBuf* Source, const char **pStart, char separator)
+{
+       StrBuf tmp;
+       char buf[64];
+       
+       tmp.buf = buf;
+       buf[0] = '\0';
+       tmp.BufSize = 64;
+       tmp.BufUsed = 0;
+       tmp.ConstBuf = 1;
+       if (StrBufExtract_NextToken(&tmp, Source, pStart, separator) > 0)
+               return(atoi(buf));
+       else
+               return 0;
+}
+
+/**
+ * \brief a string tokenizer to fetch a long integer
+ * \param dest Destination StringBuffer
+ * \param parmnum n'th parameter to extract
+ * \param separator tokenizer param
+ * \returns 0 if not found, else long integer representation of the token
+ */
+long StrBufExtractNext_long(const StrBuf* Source, const char **pStart, char separator)
+{
+       StrBuf tmp;
+       char buf[64];
+       
+       tmp.buf = buf;
+       buf[0] = '\0';
+       tmp.BufSize = 64;
+       tmp.BufUsed = 0;
+       tmp.ConstBuf = 1;
+       if (StrBufExtract_NextToken(&tmp, Source, pStart, separator) > 0)
+               return(atoi(buf));
+       else
+               return 0;
+}
+
+
+/**
+ * \brief a string tokenizer to fetch an unsigned long
+ * \param dest Destination StringBuffer
+ * \param parmnum n'th parameter to extract
+ * \param separator tokenizer param
+ * \returns 0 if not found, else unsigned long representation of the token
+ */
+unsigned long StrBufExtractNext_unsigned_long(const StrBuf* Source, const char **pStart, char separator)
+{
+       StrBuf tmp;
+       char buf[64];
+       char *pnum;
+       
+       tmp.buf = buf;
+       buf[0] = '\0';
+       tmp.BufSize = 64;
+       tmp.BufUsed = 0;
+       tmp.ConstBuf = 1;
+       if (StrBufExtract_NextToken(&tmp, Source, pStart, separator) > 0) {
+               pnum = &buf[0];
+               if (*pnum == '-')
+                       pnum ++;
+               return (unsigned long) atol(pnum);
+       }
+       else 
+               return 0;
+}
+
+
+
 /**
  * \brief Read a line from socket
  * flushes and closes the FD on error
@@ -1041,7 +1248,7 @@ int StrBufTCP_read_line(StrBuf *buf, int *fd, int append, const char **Error)
                        break;
                if (buf->buf[len] != '\r')
                        len ++;
-               if (!(len < buf->BufSize)) {
+               if (len >= buf->BufSize) {
                        buf->BufUsed = len;
                        buf->buf[len+1] = '\0';
                        IncreaseBuf(buf, 1, -1);
@@ -1165,7 +1372,7 @@ int StrBufReadBLOB(StrBuf *Buf, int *fd, int append, long nBytes, const char **E
                return -1;
        if (!append)
                FlushStrBuf(Buf);
-       if (Buf->BufUsed + nBytes > Buf->BufSize)
+       if (Buf->BufUsed + nBytes >= Buf->BufSize)
                IncreaseBuf(Buf, 1, Buf->BufUsed + nBytes);
 
        ptr = Buf->buf + Buf->BufUsed;
@@ -1499,6 +1706,25 @@ int StrBufDecodeBase64(StrBuf *Buf)
        return siz;
 }
 
+/**
+ * \brief replace all chars >0x20 && < 0x7F with Mute
+ * \param Mute char to put over invalid chars
+ * \param Buf Buffor to transform
+ */
+int StrBufSanitizeAscii(StrBuf *Buf, const char Mute)
+{
+       unsigned char *pch;
+
+       if (Buf == NULL) return -1;
+       pch = (unsigned char *)Buf->buf;
+       while (pch < (unsigned char *)Buf->buf + Buf->BufUsed) {
+               if ((*pch < 0x20) || (*pch > 0x7F))
+                       *pch = Mute;
+               pch ++;
+       }
+       return Buf->BufUsed;
+}
+
 
 /**
  * \brief  remove escaped strings from i.e. the url string (like %20 for blanks)
@@ -1588,12 +1814,12 @@ int StrBufRFC2047encode(StrBuf **target, const StrBuf *source)
        }
        if (*target == NULL)
                *target = NewStrBufPlain(NULL, sizeof(headerStr) + source->BufUsed * 2);
-       else if (sizeof(headerStr) + source->BufUsed > (*target)->BufSize)
+       else if (sizeof(headerStr) + source->BufUsed >= (*target)->BufSize)
                IncreaseBuf(*target, sizeof(headerStr) + source->BufUsed, 0);
        memcpy ((*target)->buf, headerStr, sizeof(headerStr) - 1);
        (*target)->BufUsed = sizeof(headerStr) - 1;
        for (i=0; (i < source->BufUsed); ++i) {
-               if ((*target)->BufUsed + 4 > (*target)->BufSize)
+               if ((*target)->BufUsed + 4 >= (*target)->BufSize)
                        IncreaseBuf(*target, 1, 0);
                ch = (unsigned char) source->buf[i];
                if ((ch < 32) || (ch > 126) || (ch == 61)) {
@@ -1606,7 +1832,7 @@ int StrBufRFC2047encode(StrBuf **target, const StrBuf *source)
                }
        }
        
-       if ((*target)->BufUsed + 4 > (*target)->BufSize)
+       if ((*target)->BufUsed + 4 >= (*target)->BufSize)
                IncreaseBuf(*target, 1, 0);
 
        (*target)->buf[(*target)->BufUsed++] = '?';
@@ -1698,7 +1924,7 @@ void StrBufConvert(StrBuf *ConvertBuf, StrBuf *TmpBuf, void *pic)
        size_t obuflen;                 /**< Length of output buffer */
 
 
-       if (ConvertBuf->BufUsed > TmpBuf->BufSize)
+       if (ConvertBuf->BufUsed >= TmpBuf->BufSize)
                IncreaseBuf(TmpBuf, 0, ConvertBuf->BufUsed);
 
        ic = *(iconv_t*)pic;
@@ -1964,7 +2190,7 @@ int StrBufSipLine(StrBuf *LineBuf, StrBuf *Buf, const char **Ptr)
 
        optr = LineBuf->buf;
        eptr = Buf->buf + Buf->BufUsed;
-       xptr = LineBuf->buf + LineBuf->BufSize;
+       xptr = LineBuf->buf + LineBuf->BufSize - 1;
 
        while ((*ptr != '\n') &&
               (*ptr != '\r') &&
@@ -1976,7 +2202,7 @@ int StrBufSipLine(StrBuf *LineBuf, StrBuf *Buf, const char **Ptr)
                        LineBuf->BufUsed = optr - LineBuf->buf;
                        IncreaseBuf(LineBuf,  1, LineBuf->BufUsed + 1);
                        optr = LineBuf->buf + LineBuf->BufUsed;
-                       xptr = LineBuf->buf + LineBuf->BufSize;
+                       xptr = LineBuf->buf + LineBuf->BufSize - 1;
                }
        }
        LineBuf->BufUsed = optr - LineBuf->buf;