diff options
author | Timothy Pearson <kb9vqf@pearsoncomputing.net> | 2013-07-24 15:57:00 -0500 |
---|---|---|
committer | Timothy Pearson <kb9vqf@pearsoncomputing.net> | 2013-07-24 15:57:00 -0500 |
commit | b888c7edb54e483ec0e3c2e2ce0eafd73acdcc65 (patch) | |
tree | 7ca76d42f66fb21ea08142de9a8d3bf16e597404 /kshowmail/decodeRFC2047.cpp | |
download | kshowmail-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.cpp | 182 |
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; +} + |