blob: a75742780a3e7ad48bf888fda53bce5b072be7f1 [file]
#include "stralloc.h"
#include "strerr.h"
#include "error.h"
#include "case.h"
#include "byte.h"
#include "uint32.h"
#include "mime.h"
#include "messages.h"
#include "die.h"
#include "idx.h"
void decodeHDR(const char *indata,
unsigned int n,
stralloc *outdata)
/* decodes indata depending on charset. May put '\n' and '\0' into out */
/* data and can take them as indata. */
{
const char *cp,*cpnext,*cpstart,*cpenc,*cptxt,*cpend,*cpafter;
cpnext = indata;
cpafter = cpnext + n;
cpstart = cpnext;
if (!stralloc_copys(outdata,"")) die_nomem();
if (!stralloc_ready(outdata,n)) die_nomem();
for (;;) {
cpstart = cpstart + byte_chr(cpstart,cpafter-cpstart,'=');
if (cpstart == cpafter)
break;
++cpstart;
if (*cpstart != '?')
continue;
++cpstart;
cpenc = cpstart + byte_chr(cpstart,cpafter-cpstart,'?');
if (cpenc == cpafter)
continue;
cpenc++;
cptxt = cpenc + byte_chr(cpenc,cpafter-cpenc,'?');
if (cptxt == cpafter)
continue;
cptxt++;
cpend = cptxt + byte_chr(cptxt,cpafter-cptxt,'?');
if (cpend == cpafter || *(cpend + 1) != '=')
continue;
/* We'll decode anything. On lists with many charsets, this may */
/* result in unreadable subjects, but that's the case even if */
/* no decoding is done. This way, the subject will be optimal */
/* for threading, but charset info is lost. We aim to correctly */
/* decode us-ascii and all iso-8859/2022 charsets. Exacly how */
/* these will be displayed depends on dir/charset. */
cp = cpnext;
/* scrap lwsp between coded strings */
while (*cp == ' ' || *cp == '\t')
cp++;
if (cp != cpstart - 2)
if (!stralloc_catb(outdata,cpnext, cpstart - cpnext - 2))
die_nomem();
cpnext = cp + 1;
cpstart = cpnext;
switch (*cpenc) {
case 'b':
case 'B':
decodeB(cptxt,cpend-cptxt,outdata);
cpnext = cpend + 2;
cpstart = cpnext;
break;
case 'q':
case 'Q':
decodeQ(cptxt,cpend-cptxt,outdata);
cpnext = cpend + 2;
cpstart = cpnext;
break;
default: /* shouldn't happen, but let's be reasonable */
cpstart = cpend + 2;
break;
}
}
if (!stralloc_catb(outdata,cpnext,indata-cpnext+n)) die_nomem();
}