From ff0021ec0349b708794737b452157e399c67eae7 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Wilfried=20G=C3=B6esgens?= Date: Sun, 2 Nov 2008 23:12:59 +0000 Subject: [PATCH] * reference free handler (Don't free payload ;-) * Blob to line chopper: StrBufSipLine() * buffer iconv wrapper: StrBufConvert() --- libcitadel/lib/hash.c | 9 +++ libcitadel/lib/libcitadel.h | 4 ++ libcitadel/lib/stringbuf.c | 124 ++++++++++++++++++++++++++++-------- 3 files changed, 109 insertions(+), 28 deletions(-) diff --git a/libcitadel/lib/hash.c b/libcitadel/lib/hash.c index d6c5b4745..a8340f493 100644 --- a/libcitadel/lib/hash.c +++ b/libcitadel/lib/hash.c @@ -712,5 +712,14 @@ void generic_free_handler(void *ptr) { free(ptr); } +/* + * Generic function to free a reference. + * since a reference actualy isn't needed to be freed, do nothing. + */ +void reference_free_handler(void *ptr) +{ + 1; +} + diff --git a/libcitadel/lib/libcitadel.h b/libcitadel/lib/libcitadel.h index c89a511d4..66d15c2b0 100644 --- a/libcitadel/lib/libcitadel.h +++ b/libcitadel/lib/libcitadel.h @@ -236,6 +236,7 @@ int StrBufTCP_read_buffered_line(StrBuf *Line, 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); int StrBufSub(StrBuf *dest, const StrBuf *Source, size_t Offset, size_t nChars); unsigned long StrBufExtract_unsigned_long(const StrBuf* Source, int parmnum, char separator); @@ -262,6 +263,8 @@ void StrBufEUid_escapize(StrBuf *target, const StrBuf *source); void StrBufReplaceChars(StrBuf *buf, char search, char replace); int CompressBuffer(StrBuf *Buf); +void StrBufConvert(StrBuf *ConvertBuf, StrBuf *TmpBuf, void *pic); +void ctdl_iconv_open(const char *tocode, const char *fromcode, void *pic); void StrBuf_RFC822_to_Utf8(StrBuf *Target, StrBuf *DecodeMe, const StrBuf* DefaultCharset); int StrBufDecodeBase64(StrBuf *Buf); int StrBufRFC2047encode(StrBuf **target, const StrBuf *source); @@ -397,6 +400,7 @@ int GetCount(HashList *Hash); const void *GetSearchPayload(const void *HashVoid); void SortByPayload(HashList *Hash, CompareFunc SortBy); void generic_free_handler(void *ptr); +void reference_free_handler(void *ptr); void convert_spaces_to_underscores(char *str); diff --git a/libcitadel/lib/stringbuf.c b/libcitadel/lib/stringbuf.c index 892f99e31..ab7dfb886 100644 --- a/libcitadel/lib/stringbuf.c +++ b/libcitadel/lib/stringbuf.c @@ -1511,8 +1511,9 @@ void StrBufReplaceChars(StrBuf *buf, char search, char replace) * tocode Target encoding * fromcode Source encoding */ -static iconv_t ctdl_iconv_open(const char *tocode, const char *fromcode) +void ctdl_iconv_open(const char *tocode, const char *fromcode, void *pic) { +#ifdef HAVE_ICONV iconv_t ic = (iconv_t)(-1) ; ic = iconv_open(tocode, fromcode); if (ic == (iconv_t)(-1) ) { @@ -1524,11 +1525,11 @@ static iconv_t ctdl_iconv_open(const char *tocode, const char *fromcode) ic = iconv_open(tocode, alias_fromcode); } } - return(ic); + *(iconv_t *)pic = ic; +#endif } -#ifdef HAVE_ICONV static inline char *FindNextEnd (StrBuf *Buf, char *bptr) { @@ -1555,6 +1556,46 @@ static inline char *FindNextEnd (StrBuf *Buf, char *bptr) } +void StrBufConvert(StrBuf *ConvertBuf, StrBuf *TmpBuf, void *pic) +{ +#ifdef HAVE_ICONV + int BufSize; + iconv_t ic; + char *ibuf; /**< Buffer of characters to be converted */ + char *obuf; /**< Buffer for converted characters */ + size_t ibuflen; /**< Length of input buffer */ + size_t obuflen; /**< Length of output buffer */ + + + if (ConvertBuf->BufUsed > TmpBuf->BufSize) + IncreaseBuf(TmpBuf, 0, ConvertBuf->BufUsed); + + ic = *(iconv_t*)pic; + ibuf = ConvertBuf->buf; + ibuflen = ConvertBuf->BufUsed; + obuf = TmpBuf->buf; + obuflen = TmpBuf->BufSize; + + iconv(ic, &ibuf, &ibuflen, &obuf, &obuflen); + + /* little card game: wheres the red lady? */ + ibuf = ConvertBuf->buf; + BufSize = ConvertBuf->BufSize; + + ConvertBuf->buf = TmpBuf->buf; + ConvertBuf->BufSize = TmpBuf->BufSize; + ConvertBuf->BufUsed = TmpBuf->BufSize - obuflen; + ConvertBuf->buf[ConvertBuf->BufUsed] = '\0'; + + TmpBuf->buf = ibuf; + TmpBuf->BufSize = BufSize; + TmpBuf->BufUsed = 0; + TmpBuf->buf[0] = '\0'; +#endif +} + + + inline static void DecodeSegment(StrBuf *Target, StrBuf *DecodeMe, @@ -1567,10 +1608,6 @@ inline static void DecodeSegment(StrBuf *Target, char charset[128]; char encoding[16]; iconv_t ic = (iconv_t)(-1); - char *ibuf; /**< Buffer of characters to be converted */ - char *obuf; /**< Buffer for converted characters */ - size_t ibuflen; /**< Length of input buffer */ - size_t obuflen; /**< Length of output buffer */ /* Now we handle foreign character sets properly encoded * in RFC2047 format. @@ -1582,12 +1619,12 @@ inline static void DecodeSegment(StrBuf *Target, extract_token(encoding, SegmentStart, 2, '?', sizeof encoding); StrBufExtract_token(ConvertBuf, &StaticBuf, 3, '?'); - if (!strcasecmp(encoding, "B")) { /**< base64 */ + if (*encoding == 'B') { /**< base64 */ ConvertBuf2->BufUsed = CtdlDecodeBase64(ConvertBuf2->buf, ConvertBuf->buf, ConvertBuf->BufUsed); } - else if (!strcasecmp(encoding, "Q")) { /**< quoted-printable */ + else if (*encoding == 'Q') { /**< quoted-printable */ long pos; pos = 0; @@ -1606,20 +1643,11 @@ inline static void DecodeSegment(StrBuf *Target, else { StrBufAppendBuf(ConvertBuf2, ConvertBuf, 0); } - - ic = ctdl_iconv_open("UTF-8", charset); - if (ic != (iconv_t)(-1) ) { - ibuf = ConvertBuf2->buf; - obuf = ConvertBuf->buf; - ibuf = ConvertBuf2->buf; - obuflen = ConvertBuf->BufSize; - ibuflen = ConvertBuf2->BufUsed; - - iconv(ic, &ibuf, &ibuflen, &obuf, &obuflen); - ConvertBuf->BufUsed = ConvertBuf->BufSize - obuflen; - ConvertBuf->buf[ConvertBuf->BufUsed] = '\0'; - - StrBufAppendBuf(Target, ConvertBuf, 0); + + ctdl_iconv_open("UTF-8", charset, &ic); + if (ic != (iconv_t)(-1) ) { + StrBufConvert(ConvertBuf2, ConvertBuf, &ic); + StrBufAppendBuf(Target, ConvertBuf2, 0); iconv_close(ic); } else { @@ -1664,7 +1692,7 @@ void StrBuf_RFC822_to_Utf8(StrBuf *Target, StrBuf *DecodeMe, const StrBuf* Defau if (illegal_non_rfc2047_encoding) { if ( (strcasecmp(ChrPtr(DefaultCharset), "UTF-8")) && (strcasecmp(ChrPtr(DefaultCharset), "us-ascii")) ) { - ic = ctdl_iconv_open("UTF-8", ChrPtr(DefaultCharset)); + ctdl_iconv_open("UTF-8", ChrPtr(DefaultCharset), &ic); if (ic != (iconv_t)(-1) ) { long BufSize; ibuf = DecodeMe->buf; @@ -1769,10 +1797,6 @@ void StrBuf_RFC822_to_Utf8(StrBuf *Target, StrBuf *DecodeMe, const StrBuf* Defau FreeStrBuf(&ConvertBuf); FreeStrBuf(&ConvertBuf2); } -#else -void StrBuf_RFC822_to_Utf8(StrBuf **Buf, const StrBuf* DefaultCharset) {}; - -#endif @@ -1792,3 +1816,47 @@ long StrBuf_Utf8StrCut(StrBuf *Buf, int maxlen) } return Buf->BufUsed; } + + + +int StrBufSipLine(StrBuf *LineBuf, StrBuf *Buf, const char **Ptr) +{ + const char *aptr, *ptr, *eptr; + char *optr, *xptr; + + if (Buf == NULL) + return 0; + + if (*Ptr==NULL) + ptr = aptr = Buf->buf; + else + ptr = aptr = *Ptr; + + optr = LineBuf->buf; + eptr = Buf->buf + Buf->BufUsed; + xptr = LineBuf->buf + LineBuf->BufSize; + + while ((*ptr != '\n') && + (*ptr != '\r') && + (ptr < eptr)) + { + *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; + } + } + LineBuf->BufUsed = optr - LineBuf->buf; + *optr = '\0'; + if (*ptr == '\r') + ptr ++; + if (*ptr == '\n') + ptr ++; + + *Ptr = ptr; + + return Buf->BufUsed - (ptr - Buf->buf); +} -- 2.30.2