www.pudn.com > MailAccess.rar > Attachment.cs


/****************************************************************************** 
	Copyright 2003-2004 Hamid Qureshi and Unruled Boy  
	OpenPOP.Net is free software; you can redistribute it and/or modify 
	it under the terms of the Lesser GNU General Public License as published by 
	the Free Software Foundation; either version 2 of the License, or 
	(at your option) any later version. 
 
	OpenPOP.Net 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 
	Lesser GNU General Public License for more details. 
 
	You should have received a copy of the Lesser 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 
/*******************************************************************************/ 
 
/* 
*Name:			OpenPOP.MIMEParser.Attachment 
*Function:		Attachment 
*Author:		Hamid Qureshi 
*Created:		2003/8 
*Last Modified:	2004/5/28 10:19 GMT+8 by Unruled Boy 
*Description: 
*Changes:		 
*				2004/5/28 10:19 GMT+8 by grandepuffo via Unruled Boy 
*					1.Fixed a bug in parsing ContentFileName @ https://sourceforge.net/forum/message.php?msg_id=2589759 
*				2004/5/17 14:20 GMT+8 by Unruled Boy 
*					1.Fixed a bug in parsing FileName 
*				2004/5/8 17:00 GMT+8 by Unruled Boy 
*					1.Again, hopefully we have handled the NotAttachment property correctly 
*				2004/5/1 14:13 GMT+8 by Unruled Boy 
*					1.Adding three more constructors 
*					2.Adding descriptions to every public functions/property/void 
*				2004/4/29 19:05 GMT+8 by Unruled Boy 
*					1.Hopefully we have handled the NotAttachment property correctly 
*				2004/3/29 10:28 GMT+8 by Unruled Boy 
*					1.removing bugs in decoding attachment 
*				2004/3/29 17:32 GMT+8 by Unruled Boy 
*					1.support for reply message using ms-tnef  
*					2.adding detail description for every function 
*					3.cleaning up the codes 
*/ 
using System; 
using System.IO; 
using System.Text; 
using System.Text.RegularExpressions; 
 
namespace OpenPOP.MIMEParser 
{ 
	///  
	/// Summary description for Attachment. 
	///  
	public class Attachment : IComparable 
	{ 
		#region Member Variables 
		private string _contentType=null; 
		private string _contentCharset=null; 
		private string _contentFormat=null; 
		private string _contentTransferEncoding=null; 
		private string _contentDescription=null; 
		private string _contentDisposition=null; 
		private string _contentFileName=""; 
 
		private string _defaultFileName="body.htm"; 
		private string _defaultFileName2="body*.htm"; 
		private string _defaultReportFileName="report.htm"; 
		private string _defaultMIMEFileName="body.eml"; 
		private string _defaultMSTNEFFileName="winmail.dat"; 
 
//		private string _defaultFileName=""; 
//		private string _defaultFileName2=""; 
//		private string _defaultReportFileName=""; 
//		private string _defaultMIMEFileName=""; 
//		private string _defaultMSTNEFFileName=""; 
 
		private string _contentID=null; 
		private long _contentLength=0; 
		private string _rawAttachment=null; 
		private bool _inBytes=false; 
		private byte[] _rawBytes=null; 
		#endregion 
 
 
		#region Properties 
		///  
		/// raw attachment content bytes 
		///  
		public byte[] RawBytes 
		{ 
			get{return _rawBytes;} 
			set{_rawBytes=value;} 
		} 
 
		///  
		/// whether attachment is in bytes 
		///  
		public bool InBytes 
		{ 
			get{return _inBytes;} 
			set{_inBytes=value;} 
		} 
 
		///  
		/// Content length 
		///  
		public long ContentLength 
		{ 
			get{return _contentLength;} 
		} 
 
		///  
		/// verify the attachment whether it is a real attachment or not 
		///  
		/// this is so far not comprehensive and needs more work to finish 
		public bool NotAttachment 
		{ 
			get 
			{ 
				/*				if (_contentDisposition==null||_contentType==null) 
									return true; 
								else 
									return (_contentDisposition.IndexOf("attachment")==-1 && _contentType.IndexOf("text/plain")!=-1); */ 
				/*				if (_contentType==null) 
									return true; 
								else 
									return (_contentFileName!="");*/ 
				if ((_contentType==null||_contentFileName=="") && _contentID==null)//&&_contentType.ToLower().IndexOf("text/")!=-1) 
					return true; 
				else 
					return false; 
 
			} 
		} 
 
		///  
		/// Content format 
		///  
		public string ContentFormat 
		{ 
			get{return _contentFormat;} 
		} 
 
		///  
		/// Content charset 
		///  
		public string ContentCharset 
		{ 
			get{return _contentCharset;} 
		} 
 
		///  
		/// default file name 
		///  
		public string DefaultFileName 
		{ 
			get{return _defaultFileName;} 
			set{_defaultFileName=value;} 
		} 
 
		///  
		/// default file name 2 
		///  
		public string DefaultFileName2 
		{ 
			get{return _defaultFileName2;} 
			set{_defaultFileName2=value;} 
		} 
 
		///  
		/// default report file name 
		///  
		public string DefaultReportFileName 
		{ 
			get{return _defaultReportFileName;} 
			set{_defaultReportFileName=value;} 
		} 
 
		///  
		/// default MIME File Name 
		///  
		public string DefaultMIMEFileName 
		{ 
			get{return _defaultMIMEFileName;} 
			set{_defaultMIMEFileName=value;} 
		} 
 
		///  
		/// Content Type 
		///  
		public string ContentType 
		{ 
			get{return _contentType;} 
		} 
 
		///  
		/// Content Transfer Encoding 
		///  
		public string ContentTransferEncoding 
		{ 
			get{return _contentTransferEncoding;} 
		} 
 
		///  
		/// Content Description 
		///  
		public string ContentDescription 
		{ 
			get{return _contentDescription;} 
		} 
 
		///  
		/// Content File Name 
		///  
		public string ContentFileName 
		{ 
			get{return _contentFileName;} 
			set{_contentFileName=value;} 
		} 
 
		///  
		/// Content Disposition 
		///  
		public string ContentDisposition 
		{ 
			get{return _contentDisposition;} 
		} 
 
		///  
		/// Content ID 
		///  
		public string ContentID 
		{ 
			get{return _contentID;} 
		} 
 
		///  
		/// Raw Attachment 
		///  
		public string RawAttachment 
		{ 
			get{return _rawAttachment;} 
		} 
 
		///  
		/// decoded attachment in bytes 
		///  
		public byte[] DecodedAttachment 
		{ 
			get 
			{ 
				return DecodedAsBytes(); 
			} 
		} 
		#endregion 
 
 
		///  
		/// release all objects 
		///  
		~Attachment() 
		{ 
			_rawBytes=null; 
			_rawAttachment=null; 
		} 
 
		///  
		/// New Attachment 
		///  
		/// attachment bytes content 
		/// file length 
		/// file name 
		/// content type 
		public Attachment(byte[] bytAttachment, long lngFileLength, string strFileName, string strContentType) 
		{ 
			_inBytes=true; 
			_rawBytes=bytAttachment; 
			_contentLength=lngFileLength; 
			_contentFileName=strFileName; 
			_contentType=strContentType; 
		} 
 
		///  
		/// New Attachment 
		///  
		/// attachment bytes content 
		/// file name 
		/// content type 
		public Attachment(byte[] bytAttachment, string strFileName, string strContentType) 
		{ 
			_inBytes=true; 
			_rawBytes=bytAttachment; 
			_contentLength=bytAttachment.Length; 
			_contentFileName=strFileName; 
			_contentType=strContentType; 
		} 
 
		///  
		/// New Attachment 
		///  
		/// attachment content 
		/// content type 
		/// whether only parse the header or not 
		public Attachment(string strAttachment,string strContentType, bool blnParseHeader) 
		{ 
			if(!blnParseHeader) 
			{ 
				_contentFileName=_defaultMSTNEFFileName; 
				_contentType=strContentType; 
			} 
			this.NewAttachment(strAttachment,blnParseHeader); 
		} 
 
		///  
		/// New Attachment 
		///  
		/// attachment content 
		public Attachment(string strAttachment) 
		{	 
			this.NewAttachment(strAttachment,true); 
		} 
 
		///  
		/// create attachment 
		///  
		/// raw attachment text 
		/// parse header 
		private void NewAttachment(string strAttachment, bool blnParseHeader) 
		{ 
			_inBytes=false; 
 
			if(strAttachment==null) 
				throw new ArgumentNullException("strAttachment"); 
 
			StringReader srReader=new StringReader(strAttachment); 
 
			if(blnParseHeader) 
			{ 
				string strLine=srReader.ReadLine(); 
				while(Utility.IsNotNullTextEx(strLine)) 
				{ 
					ParseHeader(srReader,ref strLine); 
					if(Utility.IsOrNullTextEx(strLine)) 
						break; 
					else 
						strLine=srReader.ReadLine(); 
				} 
			} 
 
			this._rawAttachment=srReader.ReadToEnd(); 
			_contentLength=this._rawAttachment.Length; 
		} 
 
		///  
		/// Parse header fields and set member variables 
		///  
		/// string reader 
		/// header line 
		private void ParseHeader(StringReader srReader,ref string strLine) 
		{ 
			string []array=Utility.GetHeadersValue(strLine);//Regex.Split(strLine,":"); 
			string []values=Regex.Split(array[1],";");//array[1].Split(';'); 
			string strRet=null; 
 
			switch(array[0].ToUpper()) 
			{ 
				case "CONTENT-TYPE": 
					if(values.Length>0) 
						_contentType=values[0].Trim();					 
					if(values.Length>1) 
					{ 
						_contentCharset=Utility.GetQuotedValue(values[1],"=","charset"); 
					} 
					if(values.Length>2) 
					{ 
						_contentFormat=Utility.GetQuotedValue(values[2],"=","format"); 
					} 
					_contentFileName=Utility.ParseFileName(strLine); 
					if(_contentFileName=="") 
					{ 
						strRet=srReader.ReadLine(); 
						if(strRet=="") 
						{ 
							strLine=""; 
							break; 
						} 
						_contentFileName=Utility.ParseFileName(strLine); 
						if(_contentFileName=="") 
							ParseHeader(srReader,ref strRet); 
					} 
					break; 
				case "CONTENT-TRANSFER-ENCODING": 
					_contentTransferEncoding=Utility.SplitOnSemiColon(array[1])[0].Trim(); 
					break; 
				case "CONTENT-DESCRIPTION": 
					_contentDescription=Utility.DecodeText(Utility.SplitOnSemiColon(array[1])[0].Trim()); 
					break; 
				case "CONTENT-DISPOSITION": 
					if(values.Length>0) 
						_contentDisposition=values[0].Trim(); 
					 
					///reported by grandepuffo @ https://sourceforge.net/forum/message.php?msg_id=2589759 
					//_contentFileName=values[1]; 
					if(values.Length>1)  
					{ 
						_contentFileName=values[1]; 
					}  
					else  
					{ 
						_contentFileName=""; 
					} 
					 
					if(_contentFileName=="") 
						_contentFileName=srReader.ReadLine(); 
 
					_contentFileName=_contentFileName.Replace("\t",""); 
					_contentFileName=Utility.GetQuotedValue(_contentFileName,"=","filename"); 
					_contentFileName=Utility.DecodeText(_contentFileName); 
					break; 
				case "CONTENT-ID": 
					_contentID=Utility.SplitOnSemiColon(array[1])[0].Trim('<').Trim('>'); 
					break; 
			} 
		} 
 
		///  
		/// verify the encoding 
		///  
		/// encoding to verify 
		/// true if encoding 
		private bool IsEncoding(string encoding) 
		{ 
			return _contentTransferEncoding.ToLower().IndexOf(encoding.ToLower())!=-1; 
		} 
 
		///  
		/// Decode the attachment to text 
		///  
		/// Decoded attachment text 
		public string DecodeAsText() 
		{ 
			string decodedAttachment=null; 
 
			try 
			{ 
				if(_contentType.ToLower()=="message/rfc822".ToLower()) 
					decodedAttachment=Utility.DecodeText(_rawAttachment); 
				else if(_contentTransferEncoding!=null) 
				{ 
					decodedAttachment=_rawAttachment; 
 
					if(!IsEncoding("7bit")) 
					{ 
						if(IsEncoding("8bit")&&_contentCharset!=null&_contentCharset!="") 
							decodedAttachment=Utility.Change(decodedAttachment,_contentCharset); 
 
						if(Utility.IsQuotedPrintable(_contentTransferEncoding)) 
							decodedAttachment=DecodeQP.ConvertHexContent(decodedAttachment); 
						else if(IsEncoding("8bit")) 
							decodedAttachment=decodedAttachment; 
						else 
							decodedAttachment=Utility.deCodeB64s(Utility.RemoveNonB64(decodedAttachment)); 
					} 
				} 
				else if(_contentCharset!=null) 
					decodedAttachment=Utility.Change(_rawAttachment,_contentCharset);//Encoding.Default.GetString(Encoding.GetEncoding(_contentCharset).GetBytes(_rawAttachment)); 
				else 
					decodedAttachment=_rawAttachment; 
			} 
			catch 
			{ 
				decodedAttachment=_rawAttachment; 
			} 
			return decodedAttachment; 
		} 
 
		///  
		/// decode attachment to be a message object 
		///  
		/// message 
		public Message DecodeAsMessage() 
		{ 
			bool blnRet=false; 
			return new Message(ref blnRet,"",false ,_rawAttachment,false); 
		} 
 
		///  
		/// Decode the attachment to bytes 
		///  
		/// Decoded attachment bytes 
		public byte[] DecodedAsBytes() 
		{ 
			if(_rawAttachment==null) 
				return null; 
			if(_contentFileName!="") 
			{ 
				byte []decodedBytes=null; 
 
				if(_contentType!=null && _contentType.ToLower()=="message/rfc822".ToLower()) 
					decodedBytes=Encoding.Default.GetBytes(Utility.DecodeText(_rawAttachment)); 
				else if(_contentTransferEncoding!=null) 
				{ 
					string bytContent=_rawAttachment; 
 
					if(!IsEncoding("7bit")) 
					{ 
						if(IsEncoding("8bit")&&_contentCharset!=null&_contentCharset!="") 
							bytContent=Utility.Change(bytContent,_contentCharset); 
 
						if(Utility.IsQuotedPrintable(_contentTransferEncoding)) 
							decodedBytes=Encoding.Default.GetBytes(DecodeQP.ConvertHexContent(bytContent)); 
						else if(IsEncoding("8bit")) 
							decodedBytes=Encoding.Default.GetBytes(bytContent); 
						else 
							decodedBytes=Convert.FromBase64String(Utility.RemoveNonB64(bytContent)); 
					} 
					else 
						decodedBytes=Encoding.Default.GetBytes(bytContent); 
				} 
				else if(_contentCharset!=null) 
					decodedBytes=Encoding.Default.GetBytes(Utility.Change(_rawAttachment,_contentCharset));//Encoding.Default.GetString(Encoding.GetEncoding(_contentCharset).GetBytes(_rawAttachment)); 
				else 
					decodedBytes=Encoding.Default.GetBytes(_rawAttachment); 
 
				return decodedBytes; 
			} 
			else 
			{ 
				return null; 
			} 
		} 
 
		public int CompareTo(object attachment) 
		{ 
			return (this.RawAttachment.CompareTo(((Attachment)(attachment)).RawAttachment)); 
		} 
	} 
}