MimePart.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ FX-1434 / FX-1434 / 1.0 / untmp / whidbey / REDBITS / ndp / fx / src / Net / System / Net / Mail / MimePart.cs / 3 / MimePart.cs

                            using System; 
using System.IO;
using System.Text;
using System.Collections;
using System.Globalization; 
using System.Net.Mail;
 
namespace System.Net.Mime 
{
    ///  
    /// Summary description for MimePart.
    /// 
    internal class MimePart: MimeBasePart,IDisposable
    { 
        Stream stream = null;
        bool streamSet = false; 
        bool streamUsedOnce = false; 
        AsyncCallback readCallback;
        AsyncCallback writeCallback; 
        const int maxBufferSize = 0x4400;  //seems optimal for send based on perf analysis

        internal MimePart()
        { 
        }
 
        public void Dispose(){ 
            if (stream != null) {
                stream.Close(); 
            }
        }

        /* 
        // Consider removing.
        internal MimePart(Stream stream, string name){ 
            SetContent(stream, name); 
        }
        */ 

        /*
        // Consider removing.
        internal MimePart(Stream stream, string name, string mimeType){ 
            SetContent(stream, name, mimeType);
        } 
        */ 

        /* 
        // Consider removing.
        internal MimePart(Stream stream, ContentType contentType) {
            SetContent(stream, contentType);
        } 
        */
 
        internal Stream Stream { 
            get {
                return stream; 
            }
        }

 
        internal ContentDisposition ContentDisposition{
            get{ 
                return contentDisposition; 
            }
            set{ 
                contentDisposition = value;
                if(value == null){
                    ((HeaderCollection)Headers).InternalRemove(MailHeaderInfo.GetString(MailHeaderID.ContentDisposition));
                } 
                else{
                    contentDisposition.PersistIfNeeded((HeaderCollection)Headers,true); 
                } 
            }
        } 

        /*
        // Consider removing.
        internal bool Inline { 
            get {
                return ContentDisposition.Inline; 
            } 
            set {
                ContentDisposition.Inline = value; 
            }
        }
        */
 
        internal TransferEncoding TransferEncoding {
            get { 
                if (Headers[MailHeaderInfo.GetString(MailHeaderID.ContentTransferEncoding)].Equals("base64", StringComparison.OrdinalIgnoreCase)) 
                    return TransferEncoding.Base64;
                else if(Headers[MailHeaderInfo.GetString(MailHeaderID.ContentTransferEncoding)].Equals("quoted-printable", StringComparison.OrdinalIgnoreCase)) 
                    return TransferEncoding.QuotedPrintable;
                else if(Headers[MailHeaderInfo.GetString(MailHeaderID.ContentTransferEncoding)].Equals("7bit", StringComparison.OrdinalIgnoreCase))
                    return TransferEncoding.SevenBit;
                /* 
                else if (Headers[MailHeaderInfo.GetString(MailHeaderID.ContentTransferEncoding)].Equals("8bit", StringComparison.OrdinalIgnoreCase))
                    return TransferEncoding.EightBit; 
                else if (Headers[MailHeaderInfo.GetString(MailHeaderID.ContentTransferEncoding)].Equals("binary", StringComparison.OrdinalIgnoreCase)) 
                    return TransferEncoding.Binary;
                    */ 
                else
                    return TransferEncoding.Unknown;
            }
            set { 
                //QFE 4554
                if (value == TransferEncoding.Base64) { 
                    Headers[MailHeaderInfo.GetString(MailHeaderID.ContentTransferEncoding)] = "base64"; 
                }
                else if (value == TransferEncoding.QuotedPrintable) { 
                    Headers[MailHeaderInfo.GetString(MailHeaderID.ContentTransferEncoding)] = "quoted-printable";
                }
                else if (value == TransferEncoding.SevenBit) {
                    Headers[MailHeaderInfo.GetString(MailHeaderID.ContentTransferEncoding)] = "7bit"; 
                }
                else { 
                    throw new NotSupportedException(SR.GetString(SR.MimeTransferEncodingNotSupported, value)); 
                }
            } 
        }

        internal void SetContent(Stream stream){
            if (stream == null) { 
                throw new ArgumentNullException("stream");
            } 
 
            if (streamSet) {
                this.stream.Close(); 
                this.stream = null;
                streamSet = false;
            }
 
            this.stream = stream;
            streamSet = true; 
            streamUsedOnce = false; 
            TransferEncoding = TransferEncoding.Base64;
        } 

        /*
        // Consider removing.
        internal void SetContent(Stream stream, string name) { 
            SetContent(stream, name,null);
        } 
        */ 

        internal void SetContent(Stream stream, string name, string mimeType) { 
            if (stream == null) {
                throw new ArgumentNullException("stream");
            }
 
            if (mimeType != null && mimeType != string.Empty) {
                contentType = new ContentType(mimeType); 
            } 
            if (name != null && name != string.Empty) {
                ContentType.Name = name; 
            }
            SetContent(stream);
        }
 

        internal void SetContent(Stream stream, ContentType contentType) { 
            if (stream == null) { 
                throw new ArgumentNullException("stream");
            } 
            this.contentType = contentType;
            SetContent(stream);
        }
 

        internal void Complete(IAsyncResult result, Exception e){ 
            //if we already completed and we got called again, 
            //it mean's that there was an exception in the callback and we
            //should just rethrow it. 

            MimePartContext context = (MimePartContext)result.AsyncState;
            if (context.completed) {
                throw e; 
            }
 
            try{ 
                if(context.outputStream != null){
                    context.outputStream.Close(); 
                }
            }
            catch(Exception ex){
                if (e == null) { 
                    e = ex;
                } 
            } 
            catch {
                if (e == null) { 
                    e = new Exception(SR.GetString(SR.net_nonClsCompliantException));
                }
            }
            context.completed = true; 
            context.result.InvokeCallback(e);
        } 
 

        internal void ReadCallback(IAsyncResult result) 
        {
            if (result.CompletedSynchronously ) {
                return;
            } 

            ((MimePartContext)result.AsyncState).completedSynchronously = false; 
 
            try {
                ReadCallbackHandler(result); 
            }
            catch(Exception e){
                Complete(result,e);
            } 
            catch {
                Complete(result, new Exception(SR.GetString(SR.net_nonClsCompliantException))); 
            } 
        }
 

        internal void ReadCallbackHandler(IAsyncResult result){
            MimePartContext context = (MimePartContext)result.AsyncState;
            context.bytesLeft = Stream.EndRead(result); 
            if (context.bytesLeft > 0) {
                IAsyncResult writeResult = context.outputStream.BeginWrite(context.buffer, 0, context.bytesLeft, writeCallback, context); 
                if (writeResult.CompletedSynchronously) { 
                    WriteCallbackHandler(writeResult);
                } 
            }
            else {
                Complete(result,null);
            } 
        }
 
 
        internal void WriteCallback(IAsyncResult result)
        { 
            if (result.CompletedSynchronously ) {
                return;
            }
 
            ((MimePartContext)result.AsyncState).completedSynchronously = false;
 
            try { 
                WriteCallbackHandler(result);
            } 
            catch (Exception e) {
                Complete(result,e);
            }
            catch { 
                Complete(result, new Exception(SR.GetString(SR.net_nonClsCompliantException)));
            } 
        } 

 

        internal void WriteCallbackHandler(IAsyncResult result){
            MimePartContext context = (MimePartContext)result.AsyncState;
            context.outputStream.EndWrite(result); 
            IAsyncResult readResult = Stream.BeginRead(context.buffer, 0, context.buffer.Length, readCallback, context);
            if (readResult.CompletedSynchronously) { 
                ReadCallbackHandler(readResult); 
            }
        } 


        internal Stream GetEncodedStream(Stream stream){
            Stream outputStream = stream; 

            if (TransferEncoding == TransferEncoding.Base64) { 
                outputStream = new Base64Stream(outputStream); 
            }
            else if (TransferEncoding == TransferEncoding.QuotedPrintable) { 
                outputStream = new QuotedPrintableStream(outputStream,true);
            }
            else if (TransferEncoding == TransferEncoding.SevenBit) {
                outputStream = new SevenBitStream(outputStream); 
            }
 
            return outputStream; 
        }
 
        internal void ContentStreamCallbackHandler(IAsyncResult result){

            MimePartContext context = (MimePartContext)result.AsyncState;
            Stream outputStream = context.writer.EndGetContentStream(result); 
            context.outputStream = GetEncodedStream(outputStream);
 
            readCallback = new AsyncCallback(ReadCallback); 
            writeCallback = new AsyncCallback(WriteCallback);
            IAsyncResult readResult = Stream.BeginRead(context.buffer, 0, context.buffer.Length,readCallback, context); 
            if (readResult.CompletedSynchronously) {
                ReadCallbackHandler(readResult);
            }
        } 

 
        internal void ContentStreamCallback(IAsyncResult result) 
        {
            if (result.CompletedSynchronously ) { 
                return;
            }

            ((MimePartContext)result.AsyncState).completedSynchronously = false; 

            try{ 
                ContentStreamCallbackHandler(result); 
            }
            catch (Exception e) { 
                Complete(result,e);
            }
            catch {
                Complete(result, new Exception(SR.GetString(SR.net_nonClsCompliantException))); 
            }
        } 
 

        internal class MimePartContext 
        {
            internal MimePartContext(BaseWriter writer, LazyAsyncResult result)
            {
                this.writer = writer; 
                this.result = result;
                buffer = new byte[maxBufferSize]; 
            } 

            internal Stream outputStream; 
            internal LazyAsyncResult result;
            internal int bytesLeft;
            internal BaseWriter writer;
            internal byte[] buffer; 
            internal bool completed;
            internal bool completedSynchronously = true; 
        } 

 
        internal override IAsyncResult BeginSend(BaseWriter writer, AsyncCallback callback, object state)
        {
            writer.WriteHeaders(Headers);
            MimePartAsyncResult result = new MimePartAsyncResult(this, state, callback); 
            MimePartContext context = new MimePartContext(writer, result);
 
            ResetStream(); 
            streamUsedOnce = true;
            IAsyncResult contentResult = writer.BeginGetContentStream(new AsyncCallback(ContentStreamCallback),context); 
            if (contentResult.CompletedSynchronously) {
                ContentStreamCallbackHandler(contentResult);
            }
            return result; 
        }
 
 
        internal override void Send(BaseWriter writer) {
            if (Stream != null) { 
                byte[] buffer = new byte[maxBufferSize];

                writer.WriteHeaders(Headers);
 
                Stream outputStream = writer.GetContentStream();
                outputStream = GetEncodedStream(outputStream); 
 
                int read;
 
                ResetStream();
                streamUsedOnce = true;

                while ((read = Stream.Read(buffer, 0, maxBufferSize)) > 0) { 
                    outputStream.Write(buffer, 0, read);
                } 
                outputStream.Close(); 
            }
        } 


        //Ensures that if we've used the stream once, we will either reset it to the origin, or throw.
        internal void ResetStream(){ 
            if (streamUsedOnce) {
                if (Stream.CanSeek) { 
                    Stream.Seek(0,SeekOrigin.Begin); 
                    streamUsedOnce = false;
                } 
                else{
                    throw new InvalidOperationException(SR.GetString(SR.MimePartCantResetStream));
                }
            } 
        }
    } 
} 


                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK