/*************************************************************************** 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 */ TQCString decodeQuotedPrintable(const TQCString& aStr) { TQCString bStr = aStr; if (aStr.isNull()) bStr = ""; DwString dwsrc(bStr.data()); DwString dwdest; DwDecodeQuotedPrintable(dwsrc, dwdest); return dwdest.c_str(); } TQCString decodeBase64(const TQCString& aStr) { TQCString bStr = aStr; if (aStr.isNull()) bStr = ""; while (bStr.length() < 16) bStr += "="; DwString dwsrc(bStr.data(), bStr.length()); DwString dwdest; TQCString result; DwDecodeBase64(dwsrc, dwdest); result = dwdest.c_str(); return result; } TQTextCodec* codecForName(const TQCString& _str) { if (_str.isEmpty()) return NULL; if (_str.lower() == "shift_jis" || _str.lower() == "shift-jis") return TQTextCodec::codecForName("sjis"); return TQTextCodec::codecForName(_str.lower().replace( TQRegExp("windows"), "cp") ); } TQString Codecs::decodeRFC2047(const TQCString& aStr) { TQString result; TQCString charset; char *pos, *beg, *end, *mid; TQCString str, cstr, LWSP_buffer; char encoding, ch; bool valid, lastWasEncodedWord=FALSE; const int maxLen=200; int i; if (aStr.find("=?") < 0) return TQString::fromLocal8Bit(aStr).replace(TQRegExp("\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) 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) valid = FALSE; } if (valid) { // valid encoding: decode and throw away separating LWSP ch = *pos; *pos = '\0'; str = TQCString(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); } TQTextCodec *codec = codecForName(charset); if (!codec) codec = codecForName(TDEGlobal::locale()->encoding()); if (codec) result += codec->toUnicode(cstr); else result += TQString::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; }