You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
183 lines
4.8 KiB
183 lines
4.8 KiB
/***************************************************************************
|
|
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 && (*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 = 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;
|
|
}
|
|
|