summaryrefslogtreecommitdiffstats
path: root/kshowmail/decodeRFC2047.cpp
diff options
context:
space:
mode:
authorTimothy Pearson <kb9vqf@pearsoncomputing.net>2013-07-24 15:57:00 -0500
committerTimothy Pearson <kb9vqf@pearsoncomputing.net>2013-07-24 15:57:00 -0500
commitb888c7edb54e483ec0e3c2e2ce0eafd73acdcc65 (patch)
tree7ca76d42f66fb21ea08142de9a8d3bf16e597404 /kshowmail/decodeRFC2047.cpp
downloadkshowmail-b888c7edb54e483ec0e3c2e2ce0eafd73acdcc65.tar.gz
kshowmail-b888c7edb54e483ec0e3c2e2ce0eafd73acdcc65.zip
Initial import from kshowmail 3.3.1 sources
Diffstat (limited to 'kshowmail/decodeRFC2047.cpp')
-rw-r--r--kshowmail/decodeRFC2047.cpp182
1 files changed, 182 insertions, 0 deletions
diff --git a/kshowmail/decodeRFC2047.cpp b/kshowmail/decodeRFC2047.cpp
new file mode 100644
index 0000000..adf53de
--- /dev/null
+++ b/kshowmail/decodeRFC2047.cpp
@@ -0,0 +1,182 @@
+/***************************************************************************
+ decodeRFC2047.cpp - description
+ -------------------
+ begin : Mon Jan 28 2002
+ copyright : (C) 2002 by Eggert Ehmke
+ email : eggert.ehmke@berlin.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+
+#include "decodeRFC2047.h"
+
+/*
+ * These functions have been adapted from the KMail program
+ */
+
+QCString decodeQuotedPrintable(const QCString& aStr)
+{
+ QCString bStr = aStr;
+ if (aStr.isNull())
+ bStr = "";
+
+ DwString dwsrc(bStr.data());
+ DwString dwdest;
+
+ DwDecodeQuotedPrintable(dwsrc, dwdest);
+ return dwdest.c_str();
+}
+
+QCString decodeBase64(const QCString& aStr)
+{
+ QCString bStr = aStr;
+ if (aStr.isNull())
+ bStr = "";
+ while (bStr.length() < 16) bStr += "=";
+
+ DwString dwsrc(bStr.data(), bStr.length());
+ DwString dwdest;
+ QCString result;
+
+ DwDecodeBase64(dwsrc, dwdest);
+ result = dwdest.c_str();
+ return result;
+}
+
+QTextCodec* codecForName(const QCString& _str)
+{
+ if (_str.isEmpty()) return NULL;
+ if (_str.lower() == "shift_jis" || _str.lower() == "shift-jis")
+ return QTextCodec::codecForName("sjis");
+ return QTextCodec::codecForName(_str.lower().replace(
+ QRegExp("windows"), "cp") );
+}
+
+QString Codecs::decodeRFC2047(const QCString& aStr)
+{
+ QString result;
+ QCString charset;
+ char *pos, *beg, *end, *mid;
+ QCString str, cstr, LWSP_buffer;
+ char encoding, ch;
+ bool valid, lastWasEncodedWord=FALSE;
+ const int maxLen=200;
+ int i;
+
+ if (aStr.find("=?") < 0)
+ return QString::fromLocal8Bit(aStr).replace(QRegExp("\n[\t ]")," ");
+
+ for (pos=aStr.data(); *pos; pos++)
+ {
+ // line unfolding
+ if ( pos[0] == '\r' && pos[1] == '\n' ) {
+ pos++;
+ continue;
+ }
+ if ( pos[0] == '\n' )
+ continue;
+ // collect LWSP after encoded-words,
+ // because we might need to throw it out
+ // (when the next word is an encoded-word)
+ if ( lastWasEncodedWord && ( pos[0] == ' ' || pos[0] == '\t' ) )
+ {
+ LWSP_buffer += pos[0];
+ continue;
+ }
+ // verbatimly copy normal text
+ if (pos[0]!='=' || pos[1]!='?')
+ {
+ result += LWSP_buffer + pos[0];
+ LWSP_buffer = 0;
+ lastWasEncodedWord = FALSE;
+ continue;
+ }
+ // found possible encoded-word
+ beg = pos+2;
+ end = beg;
+ valid = TRUE;
+ // parse charset name
+ charset = "";
+ for (i=2,pos+=2; i<maxLen && (*pos!='?'&&(*pos==' '||ispunct(*pos)||isalnum(*pos))); i++)
+ {
+ charset += *pos;
+ pos++;
+ }
+ if (*pos!='?' || i<4 || i>=maxLen) valid = FALSE;
+ else
+ {
+ // get encoding and check delimiting question marks
+ encoding = toupper(pos[1]);
+ if (pos[2]!='?' || (encoding!='Q' && encoding!='B'))
+ valid = FALSE;
+ pos+=3;
+ i+=3;
+ }
+ if (valid)
+ {
+ mid = pos;
+ // search for end of encoded part
+ while (i<maxLen && *pos && !(*pos=='?' && *(pos+1)=='='))
+ {
+ i++;
+ pos++;
+ }
+ end = pos+2;//end now points to the first char after the encoded string
+ if (i>=maxLen || !*pos)
+ valid = FALSE;
+ }
+ if (valid)
+ {
+ // valid encoding: decode and throw away separating LWSP
+ ch = *pos;
+ *pos = '\0';
+ str = QCString(mid).left((int)(mid - pos - 1));
+ if (encoding == 'Q')
+ {
+ // decode quoted printable text
+ for (i=str.length()-1; i>=0; i--)
+ if (str[i]=='_')
+ str[i]=' ';
+ cstr = decodeQuotedPrintable(str);
+ }
+ else
+ {
+ // decode base64 text
+ cstr = decodeBase64(str);
+ }
+ QTextCodec *codec = codecForName(charset);
+ if (!codec)
+ codec = codecForName(KGlobal::locale()->encoding());
+ if (codec)
+ result += codec->toUnicode(cstr);
+ else
+ result += QString::fromLocal8Bit(cstr);
+ lastWasEncodedWord = TRUE;
+
+ *pos = ch;
+ pos = end -1;
+ }
+ else
+ {
+ // invalid encoding, keep separating LWSP.
+ //result += "=?";
+ //pos = beg -1; // because pos gets increased shortly afterwards
+ pos = beg - 2;
+ result += LWSP_buffer;
+ result += *pos++;
+ result += *pos;
+ lastWasEncodedWord = FALSE;
+ }
+ LWSP_buffer = 0;
+ }
+ return result;
+}
+