#include <ctype.h>

#include <mimedecode.h>
#include <stringtools.h>
#include <sbase64.h>

std::string mime_qp_decode(const std::string &bufcoded,
                           bool convert_underscore)
 {
  std::string bufplain;
  int state=0;
  char qp_char1=0, qp_char2=0;

  bufplain.reserve(bufcoded.size());

  for(unsigned i=0; i<bufcoded.size(); i++)
   {
    char data=bufcoded[i];

    switch(state)
     {
     case 0:
      if(data=='=')
        state++;
      else
       {
        if(convert_underscore && data=='_')
          bufplain+=' ';
        else
          bufplain+=data;
       }
      break;

     case 1:
      if(data=='\r')
       {
       }
      else if(data=='\n')
        state=0;
      else if(isxdigit(data))
       {
        qp_char1=toupper(data);
        state++;
       }
      else
        state=0;
      break;
 
     case 2:
      if(isxdigit(data))
       {
        qp_char2=toupper(data);
        if(isdigit(qp_char1)) qp_char1-='0'; else qp_char1-='A'-10;
        if(isdigit(qp_char2)) qp_char2-='0'; else qp_char2-='A'-10;
        bufplain+=char((qp_char1<<4)|qp_char2);
       }
      state=0;
      break;
     }
   }  

  return bufplain;
 }

std::string mime_base64_decode(const std::string &bufcoded)
 {
  std::string filtered;

  filtered.reserve(bufcoded.size());

  for(unsigned i=0; i<bufcoded.size(); i++)
   {
    char data=bufcoded[i];
    switch(data)
     {
     case '\r':
     case '\n':
      break;
     default: filtered+=data;
     }
   }

  return sbase64_decode(filtered);
 }

std::string mime_decode(const mimestructt &mimestruct, const rfcmessaget &rfcm)
 {
  std::string source;

  source.assign(rfcm.data+mimestruct.offset+mimestruct.headerlen,
                mimestruct.len);

  if(stringcasecmp(mimestruct.content_transfer_encoding.value,
     "quoted-printable")==0)
   {
    return mime_qp_decode(source, FALSE);
   }
  else if(stringcasecmp(mimestruct.content_transfer_encoding.value, 
     "base64")==0)
   {
    return mime_base64_decode(source);
   }

  return source;
 }


syntax highlighted by Code2HTML, v. 0.9.1