• [Mime] MimeReader--读取Mime的帮助类 (转载)


    点击下载 MimeReader.rar

    这个类是关于MimeReader的帮助类
    看下面代码吧

    /// <summary>
    /// 类说明:Assistant
    /// 编 码 人:苏飞
    /// 联系方式:361983679  
    /// 更新网站:[url=http://www.cckan.net/thread-655-1-1.html]http://www.cckan.net/thread-655-1-1.html[/url]
    /// </summary>
    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Net.Mime;
     
    namespace DotNet.Utilities
    {
        /// <summary>
        /// This class is responsible for parsing a string array of lines
        /// containing a MIME message.
        /// </summary>
        public class MimeReader
        {
            private static readonly char[] HeaderWhitespaceChars = new char[] { ' ', '	' };
     
            private Queue<string> _lines;
            /// <summary>
            /// Gets the lines.
            /// </summary>
            /// <value>The lines.</value>
            public Queue<string> Lines
            {
                get
                {
                    return _lines;
                }
            }
     
            private MimeEntity _entity;
     
            /// <summary>
            /// Initializes a new instance of the <see cref="MimeReader"/> class.
            /// </summary>
            private MimeReader()
            {
                _entity = new MimeEntity();
            }
     
            /// <summary>
            /// Initializes a new instance of the <see cref="MimeReader"/> class.
            /// </summary>
            /// <param name="entity">The entity.</param>
            /// <param name="lines">The lines.</param>
            private MimeReader(MimeEntity entity, Queue<string> lines)
                : this()
            {
                if (entity == null)
                {
                    throw new ArgumentNullException("entity");
                }
     
                if (lines == null)
                {
                    throw new ArgumentNullException("lines");
                }
     
                _lines = lines;
                _entity = new MimeEntity(entity);
            }
     
            /// <summary>
            /// Initializes a new instance of the <see cref="MimeReader"/> class.
            /// </summary>
            /// <param name="lines">The lines.</param>
            public MimeReader(string[] lines)
                : this()
            {
                if (lines == null)
                {
                    throw new ArgumentNullException("lines");
                }
     
                _lines = new Queue<string>(lines);
            }
     
            /// <summary>
            /// Parse headers into _entity.Headers NameValueCollection.
            /// </summary>
            private int ParseHeaders()
            {
                string lastHeader = string.Empty;
                string line = string.Empty;
                // the first empty line is the end of the headers.
                while (_lines.Count > 0 && !string.IsNullOrEmpty(_lines.Peek()))
                {
                    line = _lines.Dequeue();
     
                    //if a header line starts with a space or tab then it is a continuation of the
                    //previous line.
                    if (line.StartsWith(" ") || line.StartsWith(Convert.ToString('	')))
                    {
                        _entity.Headers[lastHeader] = string.Concat(_entity.Headers[lastHeader], line);
                        continue;
                    }
     
                    int separatorIndex = line.IndexOf(':');
     
                    if (separatorIndex < 0)
                    {
                        System.Diagnostics.Debug.WriteLine("Invalid header:{0}", line);
                        continue;
                    }  //This is an invalid header field.  Ignore this line.
     
                    string headerName = line.Substring(0, separatorIndex);
                    string headerValue = line.Substring(separatorIndex + 1).Trim(HeaderWhitespaceChars);
     
                    _entity.Headers.Add(headerName.ToLower(), headerValue);
                    lastHeader = headerName;
                }
     
                if (_lines.Count > 0)
                {
                    _lines.Dequeue();
                } //remove closing header CRLF.
     
                return _entity.Headers.Count;
            }
     
            /// <summary>
            /// Processes mime specific headers.
            /// </summary>
            /// <returns>A mime entity with mime specific headers parsed.</returns>
            private void ProcessHeaders()
            {
                foreach (string key in _entity.Headers.AllKeys)
                {
                    switch (key)
                    {
                        case "content-description":
                            _entity.ContentDescription = _entity.Headers[key];
                            break;
                        case "content-disposition":
                            _entity.ContentDisposition = new ContentDisposition(_entity.Headers[key]);
                            break;
                        case "content-id":
                            _entity.ContentId = _entity.Headers[key];
                            break;
                        case "content-transfer-encoding":
                            _entity.TransferEncoding = _entity.Headers[key];
                            _entity.ContentTransferEncoding = MimeReader.GetTransferEncoding(_entity.Headers[key]);
                            break;
                        case "content-type":
                            _entity.SetContentType(MimeReader.GetContentType(_entity.Headers[key]));
                            break;
                        case "mime-version":
                            _entity.MimeVersion = _entity.Headers[key];
                            break;
                    }
                }
            }
     
            /// <summary>
            /// Creates the MIME entity.
            /// </summary>
            /// <returns>A mime entity containing 0 or more children representing the mime message.</returns>
            public MimeEntity CreateMimeEntity()
            {
                try
                {
                    ParseHeaders();
     
                    ProcessHeaders();
     
                    ParseBody();
     
                    SetDecodedContentStream();
     
                    return _entity;
                }
                catch
                {
                    return null;
     
                }
            }
     
     
            /// <summary>
            /// Sets the decoded content stream by decoding the EncodedMessage 
            /// and writing it to the entity content stream.
            /// </summary>
            /// <param name="entity">The entity containing the encoded message.</param>
            private void SetDecodedContentStream()
            {
                switch (_entity.ContentTransferEncoding)
                {
                    case System.Net.Mime.TransferEncoding.Base64:
                        _entity.Content = new MemoryStream(Convert.FromBase64String(_entity.EncodedMessage.ToString()), false);
                        break;
     
                    case System.Net.Mime.TransferEncoding.QuotedPrintable:
                        _entity.Content = new MemoryStream(GetBytes(QuotedPrintableEncoding.Decode(_entity.EncodedMessage.ToString())), false);
                        break;
     
                    case System.Net.Mime.TransferEncoding.SevenBit:
                    default:
                        _entity.Content = new MemoryStream(GetBytes(_entity.EncodedMessage.ToString()), false);
                        break;
                }
            }
     
            /// <summary>
            /// Gets a byte[] of content for the provided string.
            /// </summary>
            /// <param name="decodedContent">Content.</param>
            /// <returns>A byte[] containing content.</returns>
            private byte[] GetBytes(string content)
            {
                using (MemoryStream stream = new MemoryStream())
                {
                    using (StreamWriter writer = new StreamWriter(stream))
                    {
                        writer.Write(content);
                    }
                    return stream.ToArray();
                }
            }
     
            /// <summary>
            /// Parses the body.
            /// </summary>
            private void ParseBody()
            {
                if (_entity.HasBoundary)
                {
                    while (_lines.Count > 0
                        && !string.Equals(_lines.Peek(), _entity.EndBoundary))
                    {
                        /*Check to verify the current line is not the same as the parent starting boundary.  
                           If it is the same as the parent starting boundary this indicates existence of a 
                           new child entity. Return and process the next child.*/
                        if (_entity.Parent != null
                            && string.Equals(_entity.Parent.StartBoundary, _lines.Peek()))
                        {
                            return;
                        }
     
                        if (string.Equals(_lines.Peek(), _entity.StartBoundary))
                        {
                            AddChildEntity(_entity, _lines);
                        } //Parse a new child mime part.
                        else if (string.Equals(_entity.ContentType.MediaType, MediaTypes.MessageRfc822, StringComparison.InvariantCultureIgnoreCase)
                            && string.Equals(_entity.ContentDisposition.DispositionType, DispositionTypeNames.Attachment, StringComparison.InvariantCultureIgnoreCase))
                        {
                            /*If the content type is message/rfc822 the stop condition to parse headers has already been encountered.
                             But, a content type of message/rfc822 would have the message headers immediately following the mime
                             headers so we need to parse the headers for the attached message now.  This is done by creating
                             a new child entity.*/
                            AddChildEntity(_entity, _lines);
     
                            break;
                        }
                        else
                        {
                            _entity.EncodedMessage.Append(string.Concat(_lines.Dequeue(), Pop3Commands.Crlf));
                        } //Append the message content.
                    }
                } //Parse a multipart message.
                else
                {
                    while (_lines.Count > 0)
                    {
                        _entity.EncodedMessage.Append(string.Concat(_lines.Dequeue(), Pop3Commands.Crlf));
                    }
                } //Parse a single part message.
            }
     
            /// <summary>
            /// Adds the child entity.
            /// </summary>
            /// <param name="entity">The entity.</param>
            private void AddChildEntity(MimeEntity entity, Queue<string> lines)
            {
                /*if (entity == null)
                {
                    return;
                }
     
                if (lines == null)
                {
                    return;
                }*/
     
                MimeReader reader = new MimeReader(entity, lines);
                entity.Children.Add(reader.CreateMimeEntity());
            }
     
            /// <summary>
            /// Gets the type of the content.
            /// </summary>
            /// <param name="contentType">Type of the content.</param>
            /// <returns></returns>
            public static ContentType GetContentType(string contentType)
            {
                if (string.IsNullOrEmpty(contentType))
                {
                    contentType = "text/plain; charset=us-ascii";
                }
                return new ContentType(contentType);
     
            }
     
            /// <summary>
            /// Gets the type of the media.
            /// </summary>
            /// <param name="mediaType">Type of the media.</param>
            /// <returns></returns>
            public static string GetMediaType(string mediaType)
            {
                if (string.IsNullOrEmpty(mediaType))
                {
                    return "text/plain";
                }
                return mediaType.Trim();
            }
     
            /// <summary>
            /// Gets the type of the media main.
            /// </summary>
            /// <param name="mediaType">Type of the media.</param>
            /// <returns></returns>
            public static string GetMediaMainType(string mediaType)
            {
                int separatorIndex = mediaType.IndexOf('/');
                if (separatorIndex < 0)
                {
                    return mediaType;
                }
                else
                {
                    return mediaType.Substring(0, separatorIndex);
                }
            }
     
            /// <summary>
            /// Gets the type of the media sub.
            /// </summary>
            /// <param name="mediaType">Type of the media.</param>
            /// <returns></returns>
            public static string GetMediaSubType(string mediaType)
            {
                int separatorIndex = mediaType.IndexOf('/');
                if (separatorIndex < 0)
                {
                    if (mediaType.Equals("text"))
                    {
                        return "plain";
                    }
                    return string.Empty;
                }
                else
                {
                    if (mediaType.Length > separatorIndex)
                    {
                        return mediaType.Substring(separatorIndex + 1);
                    }
                    else
                    {
                        string mainType = GetMediaMainType(mediaType);
                        if (mainType.Equals("text"))
                        {
                            return "plain";
                        }
                        return string.Empty;
                    }
                }
            }
     
            /// <summary>
            /// Gets the transfer encoding.
            /// </summary>
            /// <param name="transferEncoding">The transfer encoding.</param>
            /// <returns></returns>
            /// <remarks>
            /// The transfer encoding determination follows the same rules as 
            /// Peter Huber's article w/ the exception of not throwing exceptions 
            /// when binary is provided as a transferEncoding.  Instead it is left
            /// to the calling code to check for binary.
            /// </remarks>
            public static TransferEncoding GetTransferEncoding(string transferEncoding)
            {
                switch (transferEncoding.Trim().ToLowerInvariant())
                {
                    case "7bit":
                    case "8bit":
                        return System.Net.Mime.TransferEncoding.SevenBit;
                    case "quoted-printable":
                        return System.Net.Mime.TransferEncoding.QuotedPrintable;
                    case "base64":
                        return System.Net.Mime.TransferEncoding.Base64;
                    case "binary":
                    default:
                        return System.Net.Mime.TransferEncoding.Unknown;
     
                }
            }
        }
    }
  • 相关阅读:
    memcached与redis 对比
    Java中的成员初始化顺序和内存分配过程
    mysql inner join,full outer join,left join,right jion
    事务 相关概念理解
    最简单的重试机制
    垃圾脚本黑我linux服务器
    趣解curl
    面试题
    Java中OutOfMemoryError(内存溢出)的三种情况及解决办法
    PermGen space
  • 原文地址:https://www.cnblogs.com/lizeyan/p/3628714.html
Copyright © 2020-2023  润新知