masqmail

diff src/header.c @ 303:3e3c280ca5b2

replaced header_fold() with a better implementation
author markus schnalke <meillo@marmaro.de>
date Thu, 09 Dec 2010 18:01:46 -0300
parents 2ffcd38ccf53
children 01d2f7a17bf0
line diff
     1.1 --- a/src/header.c	Thu Dec 09 17:50:25 2010 -0300
     1.2 +++ b/src/header.c	Thu Dec 09 18:01:46 2010 -0300
     1.3 @@ -128,78 +128,83 @@
     1.4          *(dest++) = '\0';
     1.5  }
     1.6  
     1.7 -#define MAX_HDR_LEN 72
     1.8 +/*
     1.9 +   fold the header at maxlen chars (newline excluded)
    1.10 +   (We exclude the newline because the RFCs deal with it this way)
    1.11 +*/
    1.12  void
    1.13 -header_fold(header * hdr)
    1.14 +header_fold(header* hdr, unsigned int maxlen)
    1.15  {
    1.16 -	gint len = strlen(hdr->header);
    1.17 -	gchar *p, *q;
    1.18 -	gchar *tmp_hdr;
    1.19 +	int len = strlen(hdr->header);
    1.20 +	char* src = hdr->header;
    1.21 +	char* dest;
    1.22 +	char* tmp;
    1.23 +	char* p;
    1.24  	int valueoffset;
    1.25  
    1.26 -	if (len < MAX_HDR_LEN) {
    1.27 +	if (len <= maxlen) {
    1.28  		/* we don't need to do anything */
    1.29  		return;
    1.30  	}
    1.31  
    1.32 -	/* the position in hdr->header where the value part starts */
    1.33 +	/* strip trailing whitespace */
    1.34 +	for (p=src+len-1; *p==' '||*p=='\t'||*p=='\n'; p--) {
    1.35 +		*p = '\0';
    1.36 +		len--;
    1.37 +		printf("  trailing whitespace\n");
    1.38 +	}
    1.39 +	printf("stripped len: %d\n", len);
    1.40 +
    1.41 +	/* FIXME: would be nice to have a better size calculation */
    1.42 +	/* (the current size + what we insert as break, twice as often as
    1.43 +	    we have breaks in the optimal case) */
    1.44 +	tmp = malloc(len + 2 * (len/maxlen) * strlen("\n\t"));
    1.45 +	dest = tmp;
    1.46 +
    1.47 +	/* the position in hdr->header where the value part start */
    1.48  	valueoffset = hdr->value - hdr->header;
    1.49  
    1.50 -	/* TODO: size is only calculated roughly */
    1.51 -	/* size is probably overestimated, but so we are on the safe side */
    1.52 -	/* (as much as we already have + chars inserted per break * number
    1.53 -	    of breaks + some more) */
    1.54 -	tmp_hdr = g_malloc(len + 2 * (len/MAX_HDR_LEN) + 10);
    1.55 +	while (strlen(src) > maxlen) {
    1.56 +		int i, l;
    1.57 +		char *pp;
    1.58  
    1.59 -	p = hdr->header;
    1.60 -	q = tmp_hdr;
    1.61 +		for (pp=src+maxlen; pp>src; pp--) {
    1.62 +			if (*pp==' ' || *pp=='\t' || *p=='\n') {
    1.63 +				break;
    1.64 +			}
    1.65 +		}
    1.66 +			
    1.67 +		if (src == pp) {
    1.68 +			/* no potential break point was found within
    1.69 +			   maxlen so advance further until the next */
    1.70 +			for (pp=src+maxlen; *pp; pp++) {
    1.71 +				if (*pp==' ' || *pp=='\t' || *p=='\n') {
    1.72 +					break;
    1.73 +				}
    1.74 +			}
    1.75 +		}
    1.76 +		if (!*pp) {
    1.77 +			break;
    1.78 +		}
    1.79  
    1.80 -	if (p[len - 1] == '\n') {
    1.81 -		p[len - 1] = '\0';
    1.82 +		memcpy(dest, src, pp-src);
    1.83 +		dest += pp-src;
    1.84 +		*(dest++) = '\n';
    1.85 +		*(dest++) = '\t';
    1.86 +		while (*pp == ' ' || *pp == '\t' || *p=='\n') {
    1.87 +			pp++;
    1.88 +		}
    1.89 +		src = pp;
    1.90 +	}
    1.91 +	memcpy(dest, src, strlen(src));
    1.92 +	dest += strlen(src);
    1.93 +
    1.94 +	if (*(dest-1) != '\n') {
    1.95 +		*dest = '\n';
    1.96 +		*(dest+1) = '\0';
    1.97  	}
    1.98  
    1.99 -	while (*p) {
   1.100 -		gint i, l;
   1.101 -		gchar *pp;
   1.102 -
   1.103 -		/* look forward and find potential break points */
   1.104 -		i = 0;
   1.105 -		l = -1;
   1.106 -		pp = p;
   1.107 -		while (*pp && (i < MAX_HDR_LEN)) {
   1.108 -			if ((*pp == ' ') || (*pp == '\t')) {
   1.109 -				l = i;
   1.110 -			}
   1.111 -			pp++;
   1.112 -			i++;
   1.113 -		}
   1.114 -		if (!*pp) {
   1.115 -			l = pp - p;  /* take rest, if EOS found */
   1.116 -		}
   1.117 -
   1.118 -		if (l == -1) {
   1.119 -			/* no potential break point was found within
   1.120 -			   MAX_HDR_LEN so advance further until the next */
   1.121 -			while (*pp && *pp != ' ' && *pp != '\t') {
   1.122 -				pp++;
   1.123 -				i++;
   1.124 -			}
   1.125 -			l = i;
   1.126 -		}
   1.127 -
   1.128 -		/* copy */
   1.129 -		i = 0;
   1.130 -		while (i < l) {
   1.131 -			*(q++) = *(p++);
   1.132 -			i++;
   1.133 -		}
   1.134 -		*(q++) = '\n';
   1.135 -		*(q++) = *(p++);  /* this is either space, tab or 0 */
   1.136 -		/* *(q++) = '\t'; */
   1.137 -	}
   1.138 -
   1.139 -	g_free(hdr->header);
   1.140 -	hdr->header = tmp_hdr;
   1.141 +	hdr->header = tmp;
   1.142  	hdr->value = hdr->header + valueoffset;
   1.143  }
   1.144