aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLeah Neukirchen <leah@vuxu.org>2017-03-28 01:03:40 +0200
committerLeah Neukirchen <leah@vuxu.org>2017-03-28 01:03:40 +0200
commit2d612ce1667b45112cfd09729c58170270d721ec (patch)
tree9cb18f8bb8b704b9e5635dcc376f853d31419b1d
parent6d492539d61b40137c6c863e21e3fa95c2bd2150 (diff)
downloadmblaze-2d612ce1667b45112cfd09729c58170270d721ec.tar.gz
mmime: print_header: refactor
Simplifies the code considerably. QP-header-wrapping now happens inside gen_qp. We wrap the line in advance when this will save QP-encoding, or splitting a QP-word into two. Fixes #20.
-rw-r--r--mmime.c81
1 files changed, 39 insertions, 42 deletions
diff --git a/mmime.c b/mmime.c
index 78bd757..cf08bd6 100644
--- a/mmime.c
+++ b/mmime.c
@@ -56,10 +56,10 @@ int gen_b64(uint8_t *s, off_t size)
return 0;
}
-int gen_qp(uint8_t *s, off_t size, int maxlinelen, int header)
+int gen_qp(uint8_t *s, off_t size, int maxlinelen, int linelen)
{
off_t i;
- int linelen = 0;
+ int header = linelen > 0;
char prev = 0;
for (i = 0; i < size; i++) {
@@ -90,10 +90,15 @@ int gen_qp(uint8_t *s, off_t size, int maxlinelen, int header)
prev = s[i];
}
- if (linelen >= maxlinelen-3) {
+ if (linelen >= maxlinelen-3-!!header) {
linelen = 0;
prev = '\n';
- puts("=");
+ if (header) {
+ printf("?=\n =?UTF-8?Q?");
+ linelen += 11;
+ } else {
+ puts("=");
+ }
}
}
if (linelen > 0 && !header)
@@ -192,7 +197,7 @@ print_header(char *line) {
putc_unlocked(*s++, stdout);
}
- int prevq = 0;
+ int prevq = 0; // was the previous word encoded as qp?
int linelen = s - line;
@@ -205,51 +210,43 @@ print_header(char *line) {
if ((uint8_t) *e >= 127)
highbit++;
}
- // use qp for lines with high bit, for long lines, or
- // for more than two spaces
- if (highbit ||
- e-s > 78-linelen ||
- (prevq && s[0] == ' ' && s[1] == ' ')) {
- if (!prevq && s[0] == ' ')
- s++;
- // 13 = strlen(" =?UTF-8?Q??=")
- int w;
- while (s < e && (w = (78-linelen-13) / (highbit?3:1)) < e-s && w>0) {
- printf(" =?UTF-8?Q?");
- gen_qp((uint8_t *)s, w>e-s?e-s:w, 999, 1);
- printf("?=\n");
- s += w;
+ if (!highbit) {
+ if (e-s >= 78)
+ goto force_qp;
+ if (e-s >= 78 - linelen) {
+ // wrap in advance before long word
+ printf("\n");
linelen = 0;
- prevq = 1;
}
- if (s < e) {
- if (linelen + (e-s)+13 > 78) {
- printf("\n ");
- linelen = 1;
- }
- if (highbit || s[0] == ' ') {
- printf(" =?UTF-8?Q?");
- linelen += 14;
- linelen += gen_qp((uint8_t *)s, e-s, 999, 1);
- printf("?=");
- prevq = 1;
- } else {
- fwrite(s, 1, e-s, stdout);
- linelen += e-s;
- prevq = 0;
- }
+ if (linelen <= 1 && s[0] == ' ' && s[1] == ' ') {
+ // space at beginning of line
+ goto force_qp;
}
- } else {
- if (linelen + (e-s) > 78) {
- printf("\n");
- if (*s != ' ')
- printf(" ");
- linelen = 0;
+ if (*s != ' ') {
+ printf(" ");
+ linelen++;
}
fwrite(s, 1, e-s, stdout);
linelen += e-s;
prevq = 0;
+ } else {
+force_qp:
+ if (!prevq && *s == ' ')
+ s++;
+ if (linelen >= 78 - 13 - 4 ||
+ (e-s < (78 - 13)/3 &&
+ e-s >= (78 - linelen - 13)/3)) {
+ // wrap in advance
+ printf("\n");
+ linelen = 0;
+ }
+ printf(" =?UTF-8?Q?");
+ linelen += 11;
+ linelen = gen_qp((uint8_t *)s, e-s, 78, linelen);
+ printf("?=");
+ linelen += 2;
+ prevq = 1;
}
s = e;
}