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; 
}