#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();
}

