www.pudn.com > NETINFO.rar > EmailDecode.cpp
#include "EmailDecode.h"
BOOL C7bit8bitTranferDecoder::Decode(const char* input, int inputStrlen, char* output,
int outputBufSize, int* outLength)
{
if( inputStrlen > outputBufSize )
return FALSE;
memcpy(output, input, inputStrlen);
*outLength = inputStrlen;
return TRUE;
}
#define XX 127
/*
* Table for decoding hexadecimal in quoted-printable
*/
static unsigned char index_hex[256] = {
XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
0, 1, 2, 3, 4, 5, 6, 7, 8, 9,XX,XX, XX,XX,XX,XX,
XX,10,11,12, 13,14,15,XX, XX,XX,XX,XX, XX,XX,XX,XX,
XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
XX,10,11,12, 13,14,15,XX, XX,XX,XX,XX, XX,XX,XX,XX,
XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
};
#define HEXCHAR(c) (index_hex[(unsigned char)(c)])
/*
* Table for decoding base64
*/
static unsigned char index_64[256] = {
XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,62, XX,XX,XX,63,
52,53,54,55, 56,57,58,59, 60,61,XX,XX, XX,XX,XX,XX,
XX, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 11,12,13,14,
15,16,17,18, 19,20,21,22, 23,24,25,XX, XX,XX,XX,XX,
XX,26,27,28, 29,30,31,32, 33,34,35,36, 37,38,39,40,
41,42,43,44, 45,46,47,48, 49,50,51,XX, XX,XX,XX,XX,
XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
};
#define CHAR64(c) (index_64[(unsigned char)(c)])
BOOL CQPTranferDecoder::Decode(const char* input, int inputStrlen, char* output,
int outputBufSize, int* outLength)
{
if( inputStrlen > outputBufSize )
return FALSE;
*outLength = 0;
int i = 0;
while(i < inputStrlen )
{
if( input[i] == '=' )
{
if( memcmp(input+i+1, "\r\n", 2)==0 )//skip soft line break
{
i += 3;
continue;
}
else //convert hexical number to char
{
if( HEXCHAR(input[i+1]) == XX || HEXCHAR(input[i+2]) == XX )
return FALSE;
output[ (*outLength)++ ] = HEXCHAR(input[i+1])*16 + HEXCHAR(input[i+2]);
i += 3;
}
}
else
{
output[ (*outLength)++ ] = input[i++];
}
}
return TRUE;
}
BOOL Base64Decode(const char input[4], BYTE output[3], int* pWrite)
{
if( ( CHAR64(input[0]) == XX && input[0] != '=' )
|| ( CHAR64(input[1]) == XX && input[1] != '=' )
|| ( CHAR64(input[2]) == XX && input[2] != '=' )
|| ( CHAR64(input[3]) == XX && input[3] != '=' ) )
return FALSE;
memset(output, 0, 3);
output[0] |= CHAR64(input[0])<<2;
output[0] |= CHAR64(input[1])>>4;
output[1] |= CHAR64(input[1])<<4;
output[1] |= CHAR64(input[2])>>2;
output[2] |= CHAR64(input[2])<<6;
output[2] |= CHAR64(input[3]);
for(int i=0; i<4 && input[i]!= '='; i++)NULL;
*pWrite = i*6/8;
return TRUE;
}
BOOL CBase64TranferDecoder::Decode(const char* input, int inputStrlen, char* output,
int outputBufSize, int* outLength)
{
//remove extra char such as '\r\n', SPACE, HTAB......
//store pure encoded chars in line with inputLen equal to the length of pure data line
int i,j, inputLen;
char temp[MAX_EMAIL_LINE], line[MAX_EMAIL_LINE];
sprintf(temp, "%s%s", m_szRemain, input);
memset(m_szRemain, 0, sizeof(m_szRemain));
for(i=j=0; i outputBufSize)
return FALSE;
//decoding
i = *outLength = 0;
while( i outputBufSize )
return FALSE;
*outLength = 0;
int i = 0;
while(i < inputStrlen )
{
if( input[i] == '=' )
{
if( memcmp(input+i+1, "\r\n", 2)==0 )//skip soft line break
{
i += 3;
continue;
}
else //convert hexical number to char
{
if( HEXCHAR(input[i+1]) == XX || HEXCHAR(input[i+2]) == XX )
return FALSE;
output[ (*outLength)++ ] = HEXCHAR(input[i+1])*16 + HEXCHAR(input[i+2]);
i += 3;
}
}
else
{
if( input[i] == '_' )
{
output[ (*outLength)++ ] = ' ';
i++;
}
else
{
output[ (*outLength)++ ] = input[i++];
}
}
}
return TRUE;
}
BOOL HeaderDecodeSentence(const char* input, int inputStrlen, char* output,
int outputBufSize, int *outLength)
{
BOOL result = FALSE;
int i;
if( memcmp(input, "=?", 2) == 0
&& memcmp(input + inputStrlen - 2, "?=", 2) == 0 )
{
int questionCount = 0;
for(i=2; i= 2 )
{
char *first = (char*)memchr(input+2, '?', inputStrlen-4);
char *second = (char*)memchr(first+1, '?', input + inputStrlen - 2 - ( first + 1 ));
char temp[MAX_EMAIL_LINE];
int pureLen = input + inputStrlen - 2 - ( second + 1 );
memcpy(temp, second+1, pureLen);
temp[pureLen] = 0;
//quoted-printable decoding
if( memicmp(first+1, "Q", second - first -1) == 0 )
{
if( HeaderQPDecode(temp, pureLen, output, outputBufSize-1, outLength) )
{
output[*outLength] = 0;
result = TRUE;
}
}
//base64 decoding
else if( memicmp(first+1, "B", second - first -1) == 0 )
{
CBase64TranferDecoder base64;
if( base64.Decode(temp, pureLen, output, outputBufSize-1, outLength) )
{
output[*outLength] = 0;
result = TRUE;
}
}
}
}
return result;
}
BOOL HeaderDecode(const char* input, int inputStrlen, char* output,
int outputBufSize, int *outLength)
{
BOOL result = FALSE;
if( memcmp(input, "=?", 2) == 0 )
{
const char* pBegin, *pEnd, *pSaveEnd;
char *pOutPos = output;
*outLength = 0;
for(pBegin=input,pEnd=strstr(pBegin+2, "?=");
pBegin!=NULL && pEnd!=NULL; )
{
int thisOutLen;
if( HeaderDecodeSentence(pBegin, pEnd+2-pBegin, pOutPos, outputBufSize-*outLength, &thisOutLen) )
{
result = TRUE;
*outLength += thisOutLen;
pOutPos += thisOutLen;
*pOutPos = 0;
pSaveEnd = pEnd;
pBegin = strstr(pEnd+2, "=?");
if( pBegin )
pEnd = strstr(pBegin+2, "?=");
}
else
{
result = FALSE;
break;
}
}
//copy data which isn't encoded to output buffer
//such as " hello" in "=?bg2321?B?ABSD?= hello"
if( result )
{
if( pSaveEnd+2 < input+inputStrlen )
{
memcpy(output+*outLength, pSaveEnd+2, input+inputStrlen-(pSaveEnd+2));
*outLength += input+inputStrlen-(pSaveEnd+2);
output[*outLength] = 0;
}
}
}
return result;
}