diff options
Diffstat (limited to 'camel/camel-mime-utils.c')
-rw-r--r-- | camel/camel-mime-utils.c | 128 |
1 files changed, 127 insertions, 1 deletions
diff --git a/camel/camel-mime-utils.c b/camel/camel-mime-utils.c index 5e4fcdce3b..db63e5d559 100644 --- a/camel/camel-mime-utils.c +++ b/camel/camel-mime-utils.c @@ -1021,7 +1021,7 @@ static char * header_decode_text (const char *in, int inlen) { GString *out; - const char *inptr, *inend, *start; + char *inptr, *inend, *start; char *decoded; unsigned char lastc = 0; int wasdword = FALSE; @@ -3208,6 +3208,132 @@ header_address_list_format(struct _header_address *a) return ret; } +#if 0 +static const char * +header_fold_next_space (const char *in) +{ + register const char *inptr = in; + gboolean escaped = FALSE; + + if (is_lwsp (*inptr)) + return inptr; + + do { + if (*inptr == '\\') { + escaped = TRUE; + } else if (*inptr == '"' && !escaped) { + /* find the end of this quoted section */ + for (inptr++; *inptr; inptr++) { + if (*inptr == '"' && *(inptr-1) != '\\') + break; + } + } else { + escaped = FALSE; + } + + inptr++; + } while (*inptr && !is_lwsp (*inptr)); + + if (*inptr) + return inptr; + else + return NULL; +} + +/* I wonder if this might be better for folding headers? */ +char * +header_fold (const char *in, int headerlen, gboolean force) +{ + const char *inptr = in, *space, *p, *n; + gboolean needunfold = FALSE; + int len, outlen, i; + GString *out; + char *ret; + + if (in == NULL) + return NULL; + + /* first, check to see if we even need to fold */ + len = headerlen + 2; + p = in; + while (*p) { + n = strchr (p, '\n'); + if (n == NULL) + n = p + strlen (p); + else + needunfold = TRUE; + + len += n - p; + + if (len >= CAMEL_FOLD_SIZE) + break; + len = 0; + p = n + 1; + } + + if (len < CAMEL_FOLD_SIZE) + return g_strdup (in); + + /* we need to fold, so first unfold (if we need to), then process */ + if (needunfold) + inptr = in = header_unfold (in); + + out = g_string_new (""); + outlen = headerlen + 2; + while (*inptr) { + if (force) + space = strchr (inptr, ' '); + else + space = header_fold_next_space (inptr); + + if (space) { + len = space - inptr + 1; + } else { + len = strlen (inptr); + } + + d(printf ("next word '%.*s'\n", len, inptr)); + + if (outlen + len > CAMEL_FOLD_SIZE) { + d(printf("outlen = %d wordlen = %d\n", outlen, len)); + /* strip trailing space */ + if (out->len > 0 && out->str[out->len-1] == ' ') + g_string_truncate (out, out->len-1); + g_string_append (out, "\n\t"); + outlen = 1; + + if (force) { + /* check for very long words, just cut them up */ + while (outlen + len > CAMEL_FOLD_SIZE) { + for (i = 0; i < CAMEL_FOLD_SIZE - outlen; i++) + g_string_append_c (out, inptr[i]); + inptr += CAMEL_FOLD_SIZE - outlen; + len -= CAMEL_FOLD_SIZE - outlen; + g_string_append (out, "\n\t"); + outlen = 1; + } + } + } + + outlen += len; + + for (i = 0; i < len; i++) + g_string_append_c (out, inptr[i]); + + inptr += len; + } + + ret = out->str; + g_string_free (out, FALSE); + + if (needunfold) + g_free ((char *)in); + + return ret; +} +#endif + + /* simple header folding */ /* will work even if the header is already folded */ char * |