From: Wilfried Göesgens Date: Wed, 9 Jul 2008 00:47:39 +0000 (+0000) Subject: * add new buffer class which handles concatenation of strings in dynamic buffers... X-Git-Tag: v7.86~2117 X-Git-Url: https://code.citadel.org/?p=citadel.git;a=commitdiff_plain;h=fbe839e9aa6b9e055c78d1922a06cc1be8d74675 * add new buffer class which handles concatenation of strings in dynamic buffers for itself. * adopt our algorithms to these new structures --- diff --git a/libcitadel/Makefile.in b/libcitadel/Makefile.in index 7dfeaa6da..f18a1e43e 100755 --- a/libcitadel/Makefile.in +++ b/libcitadel/Makefile.in @@ -108,6 +108,7 @@ LIB_OBJS = lib/libcitadel.lo \ lib/vnote.lo \ lib/hash.lo \ lib/lookup3.lo \ + lib/stringbuf.lo \ lib/xdgmime/xdgmime.lo \ lib/xdgmime/xdgmimeglob.lo \ lib/xdgmime/xdgmimeint.lo \ diff --git a/libcitadel/debian/changelog b/libcitadel/debian/changelog index 8bf8c3c05..0af783fe9 100644 --- a/libcitadel/debian/changelog +++ b/libcitadel/debian/changelog @@ -1,3 +1,20 @@ +libcitadel (1.09-5) stable; urgency=low + + * new upstream version + + -- Wilfried Goesgens Tue, 22 Apr 2008 19:00:00 +0002 + +libcitadel (1.08-5) stable; urgency=low + + * minor upstream bugfixes + + -- Wilfried Goesgens Mon, 17 Mar 2008 22:00:00 +0001 + +libcitadel (1.08-4) stable; urgency=high + + * release 1.08; hashing / sorting implemented + + -- Wilfried Goesgens Mo, 3 Mar 2008 22:00:00 +0001 libcitadel (1.07-8) stable; urgency=high * new upstream version diff --git a/libcitadel/debian/files b/libcitadel/debian/files index 6b5384a91..addf18a45 100644 --- a/libcitadel/debian/files +++ b/libcitadel/debian/files @@ -1,3 +1,3 @@ -libcitadel1_1.07-8_i386.deb libs optional -libcitadel1-dbg_1.07-8_i386.deb libdevel optional -libcitadel-dev_1.07-8_i386.deb libdevel optional +libcitadel1_1.09-5_i386.deb libs optional +libcitadel1-dbg_1.09-5_i386.deb libdevel optional +libcitadel-dev_1.09-5_i386.deb libdevel optional diff --git a/libcitadel/lib/hash.c b/libcitadel/lib/hash.c index 63c80e357..1de53624d 100644 --- a/libcitadel/lib/hash.c +++ b/libcitadel/lib/hash.c @@ -132,8 +132,12 @@ int dbg_PrintHash(HashList *Hash, PrintHashContent First, PrintHashContent Secon foo = Hash->LookupTable[i]->HashKey; if (First != NULL) bar = First(Hash->Members[Hash->LookupTable[i]->Position]->Data); + else + bar = ""; if (Second != NULL) bla = Second(Hash->Members[Hash->LookupTable[i]->Position]->Data); + else + bla = ""; } #ifdef DEBUG printf (" ---- Hashkey[%ld][%ld]: '%s' Value: '%s' ; %s\n", i, key, foo, bar, bla); diff --git a/libcitadel/lib/libcitadel.h b/libcitadel/lib/libcitadel.h index 32b3034db..ff9590a34 100644 --- a/libcitadel/lib/libcitadel.h +++ b/libcitadel/lib/libcitadel.h @@ -14,6 +14,7 @@ */ #include #include +#include #define LIBCITADEL_VERSION_NUMBER 737 /* @@ -199,6 +200,36 @@ void the_mime_parser(char *partnum, int dont_decode ); +typedef struct StrBuf StrBuf; + +StrBuf* NewStrBuf(void); +StrBuf* NewStrBufPlain(const char* ptr, int nChars); +StrBuf* _NewConstStrBuf(const char* StringConstant, size_t SizeOfStrConstant); +#define NewConstStrBuf(a) _NewConstStrBuf(a, sizeof(a)) +void FreeStrBuf (StrBuf **FreeMe); +void HFreeStrBuf (void *VFreeMe); +int FlushStrBuf(StrBuf *buf); + +inline const char *ChrPtr(StrBuf *Str); +inline int StrLength(StrBuf *Str); + +int StrBufTCP_read_line(StrBuf *buf, int fd, int append, const char **Error); + +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); +long StrBufExtract_long(const StrBuf* Source, int parmnum, char separator); +int StrBufExtract_int(const StrBuf* Source, int parmnum, char separator); +inline int StrBufNum_tokens(const StrBuf *source, char tok); + +void StrBufAppendBuf(StrBuf *Buf, StrBuf *AppendBuf, size_t Offset); +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); + +long StrTol(StrBuf *Buf); + const char *GuessMimeType(char *data, size_t dlen); const char* GuessMimeByFilename(const char *what, size_t len); @@ -253,6 +284,7 @@ int is_msg_in_mset(char *mset, long msgnum); int pattern2(char *search, char *patn); void stripltlen(char *, int *); char *html_to_ascii(char *inputmsg, int msglen, int screenwidth, int do_citaformat); +void LoadEntityList(char *FileName); diff --git a/libcitadel/lib/stringbuf.c b/libcitadel/lib/stringbuf.c new file mode 100644 index 000000000..a94e1d5c0 --- /dev/null +++ b/libcitadel/lib/stringbuf.c @@ -0,0 +1,416 @@ + +#include +#include +#include +#include +#include +#include "libcitadel.h" + +#include + +struct StrBuf { + char *buf; + long BufSize; + long BufUsed; + int ConstBuf; +}; + + +inline const char *ChrPtr(StrBuf *Str) +{ + if (Str == NULL) + return ""; + return Str->buf; +} + +inline int StrLength(StrBuf *Str) +{ + return Str->BufUsed; +} + +StrBuf* NewStrBuf(void) +{ + StrBuf *NewBuf; + + NewBuf = (StrBuf*) malloc(sizeof(StrBuf)); + NewBuf->buf = (char*) malloc(SIZ); + NewBuf->buf[0] = '\0'; + NewBuf->BufSize = SIZ; + NewBuf->BufUsed = 0; + NewBuf->ConstBuf = 0; + return NewBuf; +} + + +StrBuf* NewStrBufPlain(const char* ptr, int nChars) +{ + StrBuf *NewBuf; + size_t Siz = SIZ; + size_t CopySize; + + NewBuf = (StrBuf*) malloc(sizeof(StrBuf)); + if (nChars < 0) + CopySize = strlen(ptr); + else + CopySize = nChars; + + while (Siz <= CopySize) + Siz *= 2; + + NewBuf->buf = (char*) malloc(Siz); + memcpy(NewBuf->buf, ptr, CopySize); + NewBuf->buf[CopySize] = '\0'; + NewBuf->BufSize = Siz; + NewBuf->BufUsed = CopySize; + NewBuf->ConstBuf = 0; + return NewBuf; +} + +StrBuf* _NewConstStrBuf(const char* StringConstant, size_t SizeOfStrConstant) +{ + StrBuf *NewBuf; + + NewBuf = (StrBuf*) malloc(sizeof(StrBuf)); + NewBuf->buf = (char*) StringConstant; + NewBuf->BufSize = SizeOfStrConstant; + NewBuf->BufUsed = SizeOfStrConstant; + NewBuf->ConstBuf = 1; + return NewBuf; +} + + +static int IncreaseBuf(StrBuf *Buf, int KeepOriginal, int DestSize) +{ + char *NewBuf; + size_t NewSize = Buf->BufSize * 2; + + if (Buf->ConstBuf) + return -1; + + if (DestSize > 0) + while (NewSize < DestSize) + NewSize *= 2; + + NewBuf= (char*) malloc(NewSize); + if (KeepOriginal) + { + memcpy(NewBuf, Buf->buf, Buf->BufUsed); + } + else + { + NewBuf[0] = '\0'; + Buf->BufUsed = 0; + } + free (Buf->buf); + Buf->buf = NewBuf; + Buf->BufSize *= 2; + return Buf->BufSize; +} + +int FlushStrBuf(StrBuf *buf) +{ + if (buf->ConstBuf) + return -1; + buf->buf[0] ='\0'; + buf->BufUsed = 0; + return 0; +} + +void FreeStrBuf (StrBuf **FreeMe) +{ + if (!(*FreeMe)->ConstBuf) + free((*FreeMe)->buf); + free(*FreeMe); + *FreeMe = NULL; +} + +void HFreeStrBuf (void *VFreeMe) +{ + StrBuf *FreeMe = (StrBuf*)VFreeMe; + if (!FreeMe->ConstBuf) + free(FreeMe->buf); + free(FreeMe); +} + +long StrTol(StrBuf *Buf) +{ + if(Buf->BufUsed > 0) + return atol(Buf->buf); + else + return 0; +} + + +void StrBufAppendBuf(StrBuf *Buf, StrBuf *AppendBuf, size_t Offset) +{ + if ((AppendBuf == NULL) || (Buf == NULL)) + return; + if (Buf->BufSize - Offset < AppendBuf->BufUsed) + IncreaseBuf(Buf, (Buf->BufUsed > 0), AppendBuf->BufUsed); + memcpy(Buf->buf + Buf->BufUsed - 1, + AppendBuf->buf + Offset, + AppendBuf->BufUsed - Offset); + Buf->BufUsed += AppendBuf->BufUsed - Offset; + Buf->buf[Buf->BufUsed] = '\0'; +} + + +inline int StrBufNum_tokens(const StrBuf *source, char tok) +{ + return num_tokens(source->buf, tok); +} + + +int StrBufSub(StrBuf *dest, const StrBuf *Source, size_t Offset, size_t nChars) +{ + size_t NCharsRemain; + if (Offset > Source->BufUsed) + { + FlushStrBuf(dest); + return 0; + } + if (Offset + nChars < Source->BufUsed) + { + if (nChars < dest->BufSize) + IncreaseBuf(dest, 0, nChars + 1); + memcpy(dest->buf, Source->buf + Offset, nChars); + dest->BufUsed = nChars + 1; + dest->buf[dest->BufUsed] = '\0'; + return nChars; + } + NCharsRemain = Source->BufUsed - Offset; + if (NCharsRemain < dest->BufSize) + IncreaseBuf(dest, 0, NCharsRemain + 1); + memcpy(dest->buf, Source->buf + Offset, NCharsRemain); + dest->BufUsed = NCharsRemain + 1; + dest->buf[dest->BufUsed] = '\0'; + return NCharsRemain; +} + +void StrBufPrintf(StrBuf *Buf, const char *format, ...) +{ + size_t nWritten = Buf->BufSize + 1; + va_list arg_ptr; + + while (nWritten >= Buf->BufSize) { + va_start(arg_ptr, format); + nWritten = vsnprintf(Buf->buf, Buf->BufSize, format, arg_ptr); + va_end(arg_ptr); + Buf->BufUsed = nWritten ; + if (nWritten >= Buf->BufSize) + IncreaseBuf(Buf, 0, 0); + } +} + + +/** + * \brief a string tokenizer + * \param dest Destination StringBuffer + * \param Source StringBuffer to read into + * \param separator tokenizer param + * \returns -1 if not found, else length of token. + */ +int StrBufExtract_token(StrBuf *dest, const StrBuf *Source, int parmnum, char separator) +{ + const char *s; //* 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); + } + s = Source->buf; + + if (dest == NULL) { + return(-1); + } + + //cit_backtrace(); + //lprintf (CTDL_DEBUG, "test >: n: %d sep: %c source: %s \n willi \n", parmnum, separator, source); + dest->buf[0] = '\0'; + dest->BufUsed = 0; + + while (*s) { + if (*s == separator) { + ++current_token; + } + if (len >= dest->BufSize) + if (!IncreaseBuf(dest, 1, -1)) + break; + if ( (current_token == parmnum) && + (*s != separator)) { + dest->buf[len] = *s; + ++len; + } + else if (current_token > parmnum) { + break; + } + ++s; + } + + dest->buf[len] = '\0'; + dest->BufUsed = len; + + if (current_token < parmnum) { + //lprintf (CTDL_DEBUG,"test 0) + return(atoi(buf)); + else + return 0; +} + +/* + * extract_long() - extract an long parm w/o supplying a buffer + */ +long StrBufExtract_long(const StrBuf* Source, int parmnum, char separator) +{ + StrBuf tmp; + char buf[64]; + + tmp.buf = buf; + buf[0] = '\0'; + tmp.BufSize = 64; + tmp.BufUsed = 0; + if (StrBufExtract_token(&tmp, Source, parmnum, separator) > 0) + return(atoi(buf)); + else + return 0; +} + + +/* + * extract_unsigned_long() - extract an unsigned long parm + */ +unsigned long StrBufExtract_unsigned_long(const StrBuf* Source, int parmnum, char separator) +{ + StrBuf tmp; + char buf[64]; + + tmp.buf = buf; + buf[0] = '\0'; + tmp.BufSize = 64; + tmp.BufUsed = 0; + if (StrBufExtract_token(&tmp, Source, parmnum, separator) > 0) + return(atoi(buf)); + else + return 0; +} + + + +/** + * \brief Input binary data from socket + * \param buf the buffer to get the input to + * \param bytes the maximal number of bytes to read + */ +int StrBufTCP_read_line(StrBuf *buf, int fd, int append, const char **Error) +{ + int len, rlen, slen; + + if (!append) + FlushStrBuf(buf); + + slen = len = buf->BufUsed; + while (buf->buf[len] != '\n') { + rlen = read(fd, &buf->buf[len], 1); + if (rlen < 1) { + *Error = strerror(errno); + + close(fd); + + return -1; + } + if (buf->buf[len] == '\n') + break; + if (buf->buf[len] != '\r') + len ++; + if (!(len < buf->BufSize)) { + buf->BufUsed = len; + buf->buf[len+1] = '\0'; + IncreaseBuf(buf, 1, -1); + } + } + buf->BufUsed = len; + buf->buf[len] = '\0'; + return len - slen; +} + +void StrBufCutLeft(StrBuf *Buf, int nChars) +{ + if (nChars >= Buf->BufUsed) { + FlushStrBuf(Buf); + return; + } + memmove(Buf->buf, Buf->buf + nChars, Buf->BufUsed - nChars); + Buf->BufUsed -= nChars; +} + +void StrBufCutRight(StrBuf *Buf, int nChars) +{ + if (nChars >= Buf->BufUsed) { + FlushStrBuf(Buf); + return; + } + Buf->BufUsed -= nChars; + Buf->buf[Buf->BufUsed] = '\0'; +} + + +/* + * string conversion function + */ +void StrBufEUid_unescapize(StrBuf *target, StrBuf *source) +{ + int a, b, len; + char hex[3]; + int target_length = 0; + + if (target != NULL) + FlushStrBuf(target); + + if (source == NULL ||target == NULL) + { + return; + } + + len = source->BufUsed; + for (a = 0; a < len; ++a) { + if (target_length >= target->BufSize) + IncreaseBuf(target, 1, -1); + + if (source->buf[a] == '=') { + hex[0] = source->buf[a + 1]; + hex[1] = source->buf[a + 2]; + hex[2] = 0; + b = 0; + sscanf(hex, "%02x", &b); + target->buf[target_length] = b; + target->buf[++target_length] = 0; + a += 2; + } + else { + target->buf[target_length] = source->buf[a]; + target->buf[++target_length] = 0; + } + } +} +