* add VALGRIND flag to debian debug flag to make valgrind produce less noise in the...
authorWilfried Göesgens <willi@citadel.org>
Sun, 3 Aug 2008 18:04:22 +0000 (18:04 +0000)
committerWilfried Göesgens <willi@citadel.org>
Sun, 3 Aug 2008 18:04:22 +0000 (18:04 +0000)
* add QP encoding to strbuf

libcitadel/debian/rules
libcitadel/lib/libcitadel.h
libcitadel/lib/stringbuf.c

index ca93b045366d1a07e6c714f2593171eb42a03d7a..ec0451b78172cc3c7f6cab3dd0584db67e216989 100755 (executable)
@@ -12,7 +12,7 @@ DEB_BUILD_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_BUILD_GNU_TYPE)
 CFLAGS = -Wall -g
 
 ifneq (,$(findstring debug,$(DEB_BUILD_OPTIONS)))
-       CFLAGS += -O0 -ggdb -rdynamic -MD -MP -D DEBUG
+       CFLAGS += -O0 -ggdb -rdynamic -MD -MP -D DEBUG -D VALGRIND
 else
        CFLAGS += -O2
 endif
index d9f1996e403e78fdfff3bea4d9c15f0836ada7b4..68c60429d94a52fffbf91b31c6a8492d6d94ba3f 100644 (file)
@@ -211,8 +211,8 @@ void FreeStrBuf (StrBuf **FreeMe);
 void HFreeStrBuf (void *VFreeMe);
 int FlushStrBuf(StrBuf *buf);
 
-inline const char *ChrPtr(StrBuf *Str);
-inline int StrLength(StrBuf *Str);
+inline const char *ChrPtr(const StrBuf *Str);
+inline int StrLength(const StrBuf *Str);
 
 int StrBufTCP_read_line(StrBuf *buf, int *fd, int append, const char **Error);
 int StrBufReadBLOB(StrBuf *Buf, int *fd, int append, long nBytes, const char **Error);
@@ -225,7 +225,7 @@ int StrBufExtract_int(const StrBuf* Source, int parmnum, char separator);
 inline int StrBufNum_tokens(const StrBuf *source, char tok);
 
 void StrBufAppendBufPlain(StrBuf *Buf, const char *AppendBuf, long AppendSize, size_t Offset);
-void StrBufAppendBuf(StrBuf *Buf, StrBuf *AppendBuf, size_t Offset);
+void StrBufAppendBuf(StrBuf *Buf, const StrBuf *AppendBuf, size_t Offset);
 #ifdef SHOW_ME_VAPPEND_PRINTF
 /* so owe don't create an include depndency, this is just visible on demand. */
 void StrBufVAppendPrintf(StrBuf *Buf, const char *format, va_list ap);
@@ -233,13 +233,17 @@ void StrBufVAppendPrintf(StrBuf *Buf, const char *format, va_list ap);
 void StrBufPrintf(StrBuf *Buf, const char *format, ...) __attribute__((__format__(__printf__,2,3)));
 void StrBufCutLeft(StrBuf *Buf, int nChars);
 void StrBufCutRight(StrBuf *Buf, int nChars);
-void StrBufEUid_unescapize(StrBuf *target, StrBuf *source);
-void StrBufEUid_escapize(StrBuf *target, StrBuf *source);
+void StrBufEUid_unescapize(StrBuf *target, const StrBuf *source);
+void StrBufEUid_escapize(StrBuf *target, const StrBuf *source);
+
+void StrBufReplaceChars(StrBuf *buf, char search, char replace);
 
 int CompressBuffer(StrBuf *Buf);
 int StrBufDecodeBase64(StrBuf *Buf);
+int StrBufRFC2047encode(StrBuf **target, const StrBuf *source);
 
-long StrTol(StrBuf *Buf);
+long StrTol(const StrBuf *Buf);
+int StrToi(const StrBuf *Buf);
 
 const char *GuessMimeType(const char *data, size_t dlen);
 const char* GuessMimeByFilename(const char *what, size_t len);
@@ -324,6 +328,7 @@ char *vcard_get_prop(struct vCard *v, char *propname, int is_partial,
 char *vcard_serialize(struct vCard *);
 void vcard_fn_to_n(char *vname, char *n, size_t vname_size);
 void remove_charset_attribute(char *strbuf);
+long StrBufUnescape(StrBuf *Buf, int StripBlanks);
 
 /*
  * Hash list implementation for Citadel
index 0e9fb0e504f626c67d5e37cbc5568721697d978b..5a5e3985488479e750f20247870eea137eb66ed2 100644 (file)
@@ -19,14 +19,14 @@ struct StrBuf {
 };
 
 
-inline const char *ChrPtr(StrBuf *Str)
+inline const char *ChrPtr(const StrBuf *Str)
 {
        if (Str == NULL)
                return "";
        return Str->buf;
 }
 
-inline int StrLength(StrBuf *Str)
+inline int StrLength(const StrBuf *Str)
 {
        return (Str != NULL) ? Str->BufUsed : 0;
 }
@@ -146,7 +146,7 @@ void HFreeStrBuf (void *VFreeMe)
        free(FreeMe);
 }
 
-long StrTol(StrBuf *Buf)
+long StrTol(const StrBuf *Buf)
 {
        if(Buf->BufUsed > 0)
                return atol(Buf->buf);
@@ -154,6 +154,14 @@ long StrTol(StrBuf *Buf)
                return 0;
 }
 
+int StrToi(const StrBuf *Buf)
+{
+       if(Buf->BufUsed > 0)
+               return atoi(Buf->buf);
+       else
+               return 0;
+}
+
 int StrBufPlain(StrBuf *Buf, const char* ptr, int nChars)
 {
        size_t Siz = Buf->BufSize;
@@ -176,7 +184,7 @@ int StrBufPlain(StrBuf *Buf, const char* ptr, int nChars)
        return CopySize;
 }
 
-void StrBufAppendBuf(StrBuf *Buf, StrBuf *AppendBuf, size_t Offset)
+void StrBufAppendBuf(StrBuf *Buf, const StrBuf *AppendBuf, size_t Offset)
 {
        if ((AppendBuf == NULL) || (Buf == NULL))
                return;
@@ -513,7 +521,7 @@ void StrBufCutRight(StrBuf *Buf, int nChars)
 /*
  * string conversion function
  */
-void StrBufEUid_unescapize(StrBuf *target, StrBuf *source) 
+void StrBufEUid_unescapize(StrBuf *target, const StrBuf *source) 
 {
        int a, b, len;
        char hex[3];
@@ -552,7 +560,7 @@ void StrBufEUid_unescapize(StrBuf *target, StrBuf *source)
 /*
  * string conversion function
  */
-void StrBufEUid_escapize(StrBuf *target, StrBuf *source) 
+void StrBufEUid_escapize(StrBuf *target, const StrBuf *source) 
 {
        int i, len;
 
@@ -693,3 +701,128 @@ int StrBufDecodeBase64(StrBuf *Buf)
        Buf->BufUsed = siz;
        return siz;
 }
+
+
+/*   
+ * remove escaped strings from i.e. the url string (like %20 for blanks)
+ */
+long StrBufUnescape(StrBuf *Buf, int StripBlanks)
+{
+       int a, b;
+       char hex[3];
+       long len;
+
+       while ((Buf->BufUsed > 0) && (isspace(Buf->buf[Buf->BufUsed - 1]))){
+               Buf->buf[Buf->BufUsed - 1] = '\0';
+               Buf->BufUsed --;
+       }
+
+       a = 0; 
+       while (a < Buf->BufUsed) {
+               if (Buf->buf[a] == '+')
+                       Buf->buf[a] = ' ';
+               else if (Buf->buf[a] == '%') {
+                       /* don't let % chars through, rather truncate the input. */
+                       if (a + 2 > Buf->BufUsed) {
+                               Buf->buf[a] = '\0';
+                               Buf->BufUsed = a;
+                       }
+                       else {                  
+                               hex[0] = Buf->buf[a + 1];
+                               hex[1] = Buf->buf[a + 2];
+                               hex[2] = 0;
+                               b = 0;
+                               sscanf(hex, "%02x", &b);
+                               Buf->buf[a] = (char) b;
+                               len = Buf->BufUsed - a - 2;
+                               if (len > 0)
+                                       memmove(&Buf->buf[a + 1], &Buf->buf[a + 3], len);
+                       
+                               Buf->BufUsed -=2;
+                       }
+               }
+               a++;
+       }
+       return a;
+}
+
+
+/**
+ * \brief      RFC2047-encode a header field if necessary.
+ *             If no non-ASCII characters are found, the string
+ *             will be copied verbatim without encoding.
+ *
+ * \param      target          Target buffer.
+ * \param      source          Source string to be encoded.
+ * \returns     encoded length; -1 if non success.
+ */
+int StrBufRFC2047encode(StrBuf **target, const StrBuf *source)
+{
+       const char headerStr[] = "=?UTF-8?Q?";
+       int need_to_encode = 0;
+       int i = 0;
+       unsigned char ch;
+
+       if ((source == NULL) || 
+           (target == NULL))
+           return -1;
+
+       while ((i < source->BufUsed) &&
+              (!IsEmptyStr (&source->buf[i])) &&
+              (need_to_encode == 0)) {
+               if (((unsigned char) source->buf[i] < 32) || 
+                   ((unsigned char) source->buf[i] > 126)) {
+                       need_to_encode = 1;
+               }
+               i++;
+       }
+
+       if (!need_to_encode) {
+               if (*target == NULL) {
+                       *target = NewStrBufPlain(source->buf, source->BufUsed);
+               }
+               else {
+                       FlushStrBuf(*target);
+                       StrBufAppendBuf(*target, source, 0);
+               }
+               return (*target)->BufUsed;
+       }
+       if (*target == NULL)
+               *target = NewStrBufPlain(NULL, sizeof(headerStr) + source->BufUsed * 2);
+       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)
+                       IncreaseBuf(*target, 1, 0);
+               ch = (unsigned char) source->buf[i];
+               if ((ch < 32) || (ch > 126) || (ch == 61)) {
+                       sprintf(&(*target)->buf[(*target)->BufUsed], "=%02X", ch);
+                       (*target)->BufUsed += 3;
+               }
+               else {
+                       (*target)->buf[(*target)->BufUsed] = ch;
+                       (*target)->BufUsed++;
+               }
+       }
+       
+       if ((*target)->BufUsed + 4 > (*target)->BufSize)
+               IncreaseBuf(*target, 1, 0);
+
+       (*target)->buf[(*target)->BufUsed++] = '?';
+       (*target)->buf[(*target)->BufUsed++] = '=';
+       (*target)->buf[(*target)->BufUsed] = '\0';
+       return (*target)->BufUsed;;
+}
+
+void StrBufReplaceChars(StrBuf *buf, char search, char replace)
+{
+       long i;
+       if (buf == NULL)
+               return;
+       for (i=0; i<buf->BufUsed; i++)
+               if (buf->buf[i] == search)
+                       buf->buf[i] = replace;
+
+}