⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mime.cpp

📁 强大易用的邮件收发客户端
💻 CPP
字号:
// Copyright (C) 1997-2002 Valeriy Ovechkin
// 
// 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.
// 
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
// 
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
//
// Base64.cpp : implementation file
//

#include "stdafx.h"
#include "MIME.h"
#include "tools.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include "base64.h"

// see RFC 2047 <URL:http://sunsite.dk/RFC/rfc/rfc2047.html>
CString MIMEWordDecode( const CString& strInput )
{
	CString strText = strInput;

	//
	// locate character set
	//
	int iQuestionMarkPosition = strText.Find( '?' );
	if( iQuestionMarkPosition == -1 )
	{
		return strText;
	}

	CString strCharacterSet = strText.Left( iQuestionMarkPosition );
	strText = strText.Right( strText.GetLength() - iQuestionMarkPosition - 1 );
	
	//
	// locate encoding
	//
	iQuestionMarkPosition = strText.Find( '?' );
	if( iQuestionMarkPosition == -1 )
	{
		return strText;
	}
	
	CString strEncoding = strText.Left( iQuestionMarkPosition );
	strEncoding.MakeUpper();
	strText = strText.Right( strText.GetLength() - iQuestionMarkPosition - 1 );

	//
	// decode the text
	//
	if( strEncoding == "Q" )
	{
		// quoted printable
		strText = QuotedPrintableDecode( strText );
	}
	else if( strEncoding == "B" )
	{
		// base 64
		strText = Base64Decode( strText );
	}
	else
	{
		// unknown encoding
		return strText;
	}

	return strText;
}

// see RFC 2047 <URL:http://sunsite.dk/RFC/rfc/rfc2047.html>
CString MIMEStringDecode( const CString& strInput )
{
	CString strOutput;

	int iStartPosition = 0;
	while( iStartPosition < strInput.GetLength() )
	{
		int iOpeningPosition = strInput.Find( "=?", iStartPosition );

		if( iOpeningPosition == -1 )
		{
			strOutput += strInput.Mid( iStartPosition );
			break;
		}
		
		if( iOpeningPosition > iStartPosition )
		{
			strOutput += strInput.Mid( iStartPosition, iOpeningPosition - iStartPosition );
		}

		int iClosingPosition = strInput.Find( "?", iOpeningPosition + 2 );
		
		bool bFoundTerminator = false;

		if( iClosingPosition != -1 )
		{
			iClosingPosition = strInput.Find( "?", iClosingPosition + 1 );

			if( iClosingPosition != -1 )
			{
				iClosingPosition = strInput.Find( "?=", iClosingPosition + 1 );

				if( iClosingPosition != -1 )
				{
					bFoundTerminator = true;
				}
			}
		}

		if( !bFoundTerminator )
		{
			// give up
			strOutput += strInput.Mid( iStartPosition );
			break;
		}
	
		CString sEnCoded = strInput.Mid( iOpeningPosition + 2, iClosingPosition - iOpeningPosition - 2 );
		BOOL bUTF = FindIgnoreCase(sEnCoded, "utf-8?");
		BOOL bKOI = FindIgnoreCase(sEnCoded, "koi8-r?");

		CString sDecoded = MIMEWordDecode(sEnCoded);

		if (bUTF)
		{
			UTF8ToWin(sDecoded);
		}
		else if (bKOI)
		{
			KOI8ToWin(sDecoded);
		}

		strOutput += sDecoded;
		
		iStartPosition = iClosingPosition + 2;
	}

	strOutput.TrimLeft();
	strOutput.TrimRight();

	return strOutput;
}

/////////////////////////////////////////////////////////////////////////////
// QuotedPrintable

static
unsigned char DecodeQuotedPrintableValue(unsigned char c)
{
	// Note that this works only on ASCII machines.
	if ('A' <= c && c <= 'F')
		return char(c - 'A' + 10);
	if ('a' <= c && c <= 'f')
		return char(c - 'a' + 10);
	if ('0' <= c && c <= '9')
		return char(c - '0');
	
	return 0;
}

// see RFC 2045 <URL:http://sunsite.dk/RFC/rfc/rfc2045.html>
// see RFC 2047 <URL:http://sunsite.dk/RFC/rfc/rfc2047.html>
CString QuotedPrintableDecode( const CString& strInput )
{
	CString strOutput;

	int iStartPosition = 0;
	while( iStartPosition < strInput.GetLength() )
	{
		int iEqualSignPosition = strInput.Find( '=', iStartPosition );

		if( iEqualSignPosition == -1 )
		{
			strOutput += strInput.Mid( iStartPosition );
			break;
		}
		
		if( iEqualSignPosition > iStartPosition )
		{
			strOutput += strInput.Mid( iStartPosition, iEqualSignPosition - iStartPosition );
		}

		// check if we have enough (2) characters left to decode a byte
		if( strInput.GetLength() - iEqualSignPosition - 1 < 2 )
		{
			break;
		}

		strOutput +=
		(
			char(
			  (DecodeQuotedPrintableValue( strInput.GetAt( iEqualSignPosition + 1 ) ) << 4 ) | 
			  DecodeQuotedPrintableValue( strInput.GetAt( iEqualSignPosition + 2 ) ) 
			)
		);
		
		iStartPosition = iEqualSignPosition + 3;
	}

	strOutput.Replace( '_', ' ' );

	return strOutput;
}

/////////////////////////////////////////////////////////////////////////////
// Base64

static
unsigned char DecodeBase64Value(unsigned char c)
{
	// Note that this works only on ASCII machines.
	if ('A' <= c && c <= 'Z')
		return char(c - 'A');
	if ('a' <= c && c <= 'z')
		return char(c - 'a' + 26);
	if ('0' <= c && c <= '9')
		return char(c - '0' + 52);
	if (c == '+')
		return 62;
	if (c == '/')
		return 63;
	if (c == '=')
		return (unsigned char)-1;
	
	return (unsigned char)-2;
}

// see RFC 2045 <URL:http://sunsite.dk/RFC/rfc/rfc2045.html>
CString Base64Decode( const CString& strInput )
{
	CString strOutput;

	unsigned char	uchStoredChars[4];
	int		iChars = 0;

	int iLineIndex = 0;

	while(iLineIndex < strInput.GetLength() ) 
	{
		// Group together four characters for decode.
		while (iLineIndex < strInput.GetLength() && iChars < sizeof(uchStoredChars) ) 
		{
			unsigned char c = strInput.GetAt( iLineIndex++ );
			// Ignore characters that aren't BASE64 characters
            // (e.g., spaces, CRLF, etc.).
			if (DecodeBase64Value(c) != -2)
				uchStoredChars[iChars++] = c;
		}

		if (iChars == 4) 
		{
			// We've got four characters, so decode them.
			iChars = 0;

			//
			// Decode first byte.
			//
			strOutput += 
			(
				char(
				(DecodeBase64Value(uchStoredChars[0]) << 2) | 
				(DecodeBase64Value(uchStoredChars[1]) >> 4)
				)
			);

			//
			// Decode second byte.
			//
			if (uchStoredChars[2] == '=') 
				return strOutput;

			strOutput += 
			(
				char(
				(DecodeBase64Value(uchStoredChars[1]) << 4) | 
				(DecodeBase64Value(uchStoredChars[2]) >> 2)
				)
			);

			//
			// Decode third byte.
			//
			if (uchStoredChars[3] == '=') 
				return strOutput;

			strOutput += 
			(
				char(
				(DecodeBase64Value(uchStoredChars[2]) << 6) | 
				DecodeBase64Value(uchStoredChars[3])
				)
			);
		}
	}

    return strOutput;
}
/////////////////////////////////////////////////////////////////////////////

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -