|
using System;
using System.Text;
using System.IO;
using System.Collections;
using System.Collections.Specialized;
namespace HB.Web.Mail.Mime
{
/// <summary>
/// A MIME part with ASCII content.
/// </summary>
public class MimePartContent : MimePart
{
/// <summary>
/// Creates a new MIME part content object.
/// </summary>
/// <param name="content">The content of the MIME part.</param>
/// <param name="contentType">The contnet-type of the MIME part.</param>
/// <param name="boundary">The boundary of the MIME part.</param>
/// <param name="messageBoundary">The boundary of the MIME message.</param>
/// <remarks>Exceptions thrown from the base constructor are not caught.</remarks>
public MimePartContent(string contentType, string boundary, string messageBoundary, string content)
: base(contentType, boundary, messageBoundary)
{
this.content = new StringBuilder(content);
}
/// <summary>
/// Copy constructor.
/// </summary>
/// <param name="mimePartContent">The MIME part content to copy.</param>
/// <remarks>A deep copy is performed.
/// Exceptions thrown from the base constructor are not caught.</remarks>
public MimePartContent(MimePartContent mimePartContent) : base(mimePartContent)
{
content = new StringBuilder(mimePartContent.content.ToString());
}
/// <summary>
/// Extracts inner <see cref="MimePartContent"/> sections from a <see cref="MimePartContent"/>.
/// </summary>
/// <param name="content">The <see cref="MimePartContent"/> to parse.</param>
/// <returns>The inner <see cref="MimePartContent"/> sections of parameter content.</returns>
/// <exception cref="ArgumentNullException">When parameter content is null.</exception>
/// <remarks>No exception handling is performed.</remarks>
public static MimePartContent[] Parse(MimePartContent content)
{
if(content == null)
throw new ArgumentNullException("content");
StringReader data = new StringReader(content.Content);
ArrayList parts = new ArrayList();
string line = data.ReadLine();
while(line == "--" + content.Boundary)
{
parts.Add(GetMimePart(data, content.Boundary, out line));
if(line == "--" + content.Boundary + "--")
break;
}
return (MimePartContent[]) parts.ToArray(typeof(MimePartContent));
}
/// <summary>
/// Gets the <see cref="MimePartContent"/> from a text stream.
/// </summary>
/// <param name="data">The text stream.</param>
/// <param name="boundary">The <see cref="MimePart.Boundary"/> of the <see cref="MimePartContent"/>.</param>
/// <param name="line">The last line read from the text stream.</param>
/// <returns>The <see cref="MimePartContent"/> read from the text stream.</returns>
/// <remarks>No exception handling is performed.</remarks>
private static MimePartContent GetMimePart(StringReader data, string boundary, out string line)
{
if(data == null)
throw new ArgumentNullException("data");
if(boundary == null)
throw new ArgumentNullException("boundary");
if(boundary == string.Empty)
throw new ArgumentException("boundary cannot be an empty string.");
line = data.ReadLine();
StringWriter content = new StringWriter();
while(line != "")
{
content.WriteLine(line);
line = data.ReadLine();
}
content.Flush();
content.Close();
NameValueCollection hdrs;
GetHeaders(content.ToString(), out hdrs);
string contenttype = hdrs["content-type"];
MimePartContent altContent = new MimePartContent(contenttype, boundary, boundary, "");
foreach(string key in hdrs.AllKeys)
altContent.Headers[key] = hdrs[key];
content = new StringWriter();
line = data.ReadLine();
while((line != "--" + boundary) && (line != "--" + boundary + "--"))
{
content.WriteLine(line);
line = data.ReadLine();
}
content.Flush();
content.Close();
altContent.Content = content.ToString();
return altContent;
}
/// <summary>
/// Extracts the MIME portion of an e-mail.
/// </summary>
/// <param name="data">The text data of the e-mail.</param>
/// <returns>A <see cref="MimePartContent"/> containing the MIME portion of the e-mail.</returns>
/// <exception cref="ArgumentNullException">When parameter data is null.</exception>
/// <exception cref="ApplicationException">When an error occurred while parsing the text.</exception>
public static MimePartContent Parse(string data)
{
if(data == null)
throw new ArgumentNullException("data");
NameValueCollection headers;
int linesRead = GetHeaders(data, out headers);
object contentType = headers["content-type"];
if(contentType == null)
throw new ApplicationException("The content type could not be located.");
string boundary = ExtractBoundary(contentType.ToString());
StringReader lines = new StringReader(data);
for(int i = 0; i < linesRead; i++)
lines.ReadLine();
string line = null;
StringWriter content = new StringWriter();
MimePartContent part = null;
if(boundary == null)
{
//throw new ApplicationException("The content boundary could not be located.");
part = new MimePartContent(contentType.ToString(), "", "", "");
part.Headers["content-type"] = headers["content-type"];
if(headers["content-transfer-encoding"] != null)
part.Headers["content-transfer-encoding"] = headers["content-transfer-encoding"];
while(lines.Peek() != -1)
content.WriteLine(lines.ReadLine());
}
else
{
part = new MimePartContent(contentType.ToString(), boundary, boundary, "");
if(lines.Peek() == -1)
throw new ApplicationException("End of text reached prematurely.");
line = lines.ReadLine();
while(line != "--" + boundary)
{
if(lines.Peek() == -1)
throw new ApplicationException("The start boundary could not be located.");
line = lines.ReadLine();
}
content.WriteLine(line);
line = lines.ReadLine();
if(lines.Peek() == -1)
throw new ApplicationException("The end boundary could not be located.");
while(line != "--" + boundary + "--")
{
if(lines.Peek() == -1)
{
line = "--" + boundary + "--";
break;
//throw new ApplicationException("The end boundary could not be located.");
}
content.WriteLine(line);
line = lines.ReadLine();
}
content.Write(line);
}
content.Flush();
content.Close();
part.Content = content.ToString();
return part;
}
/// <summary>
/// Gets or sets the content of the MIME part.
/// </summary>
public string Content
{
get
{
return content.ToString();
}
set
{
content = new StringBuilder(value);
}
}
/// <summary>
/// Writes the MIME part content to the provided <see cref="ArpaClientStream"/>.
/// </summary>
/// <param name="stream">The <see cref="ArpaClientStream"/> to write to.</param>
/// <exception cref="ArgumentNullException">When parameter stream is null.</exception>
/// <exception cref="ApplicationException">When an error occurred while writing to the
/// arpa client stream.</exception>
public override void ToData(ArpaClientStream stream)
{
base.WriteHeader(stream);
if(stream == null)
throw new ArgumentNullException("stream");
try
{
stream.Write(ArpaTextMessage.MakeTransparent(Content));
}
catch(Exception e)
{
string msg = "An error occurred while writing data to the arpa client stream. " + e.Message;
throw new ApplicationException(msg);
}
}
/// <summary>
/// Determines if this instance of <see cref="MimePartContent"/> is equal
/// to another object.
/// </summary>
/// <param name="obj">The object to compare.</param>
/// <returns>true if parameter obj is of type <see cref="MimePartContent"/>
/// with an equal <see cref="MimePart.ContentType"/>.</returns>
public override bool Equals(object obj)
{
return ((obj is MimePartContent) && (this == ((MimePartContent)obj)));
}
/// <summary>
/// Determines if type objects of type <see cref="MimePartContent"/> are
/// equal to each other.
/// </summary>
/// <param name="lhs">An object to compare.</param>
/// <param name="rhs">An object to compare.</param>
/// <returns>true if both objects are of type <see cref="MimePartContent"/>
/// with an equal <see cref="MimePart.ContentType"/>.</returns>
public static bool operator ==(MimePartContent lhs, MimePartContent rhs)
{
if(((object)lhs == null) && ((object)rhs == null))
return true;
if(((object)lhs == null) || ((object)rhs == null))
return false;
return (lhs.ContentType == rhs.ContentType);
}
/// <summary>
/// Determines if type objects of type <see cref="MimePartContent"/> are
/// not equal to each other.
/// </summary>
/// <param name="lhs">An object to compare.</param>
/// <param name="rhs">An object to compare.</param>
/// <returns>true if one or both objects are not of type <see cref="MimePartContent"/>
/// or if both objects are of type <see cref="MimePartContent"/>
/// with a different<see cref="MimePart.ContentType"/>.</returns>
public static bool operator !=(MimePartContent lhs, MimePartContent rhs)
{
return !MimePartContent.Equals(lhs, rhs);
}
/// <summary>
/// Creates a copy of the invoked instance.
/// </summary>
/// <returns>A deep copy of the invoked instance.</returns>
/// <remarks>A deep copy is made using the copy constructor.</remarks>
public override object Clone()
{
return new MimePartContent(this);
}
/// <summary>
/// Stores the content of the MIME part.
/// </summary>
protected StringBuilder content;
}
}
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.