[Nmailserver-commits] SF.net SVN: nmailserver: [187] NMail/trunk/NMail
Brought to you by:
dframpton-oss,
tmyroadctfig
|
From: <tmy...@us...> - 2007-04-30 08:59:20
|
Revision: 187
http://svn.sourceforge.net/nmailserver/?rev=187&view=rev
Author: tmyroadctfig
Date: 2007-04-30 01:59:18 -0700 (Mon, 30 Apr 2007)
Log Message:
-----------
Further work on local store data. Restructure Message related classes. Fixed a major defect in MySql authentication. More work on unit tests.
Modified Paths:
--------------
NMail/trunk/NMail/Authentication/BasicAuthToken.cs
NMail/trunk/NMail/Authentication/IAuthenticationProvider.cs
NMail/trunk/NMail/DataTypes/ACLs/GenericAce.cs
NMail/trunk/NMail/DataTypes/ACLs/SystemPrivilege.cs
NMail/trunk/NMail/DataTypes/LocalStore/ILocalStore.cs
NMail/trunk/NMail/DataTypes/LocalStore/ILocalStoreData.cs
NMail/trunk/NMail/DataTypes/LocalStore/LocalStoreDelivery.cs
NMail/trunk/NMail/DataTypes/SmtpMessage.cs
NMail/trunk/NMail/DataTypes/Spool/SpoolEnvelope.cs
NMail/trunk/NMail/Helper/MessageHelper.cs
NMail/trunk/NMail/Helper/MimeHelper.cs
NMail/trunk/NMail/NMail.csproj
NMail/trunk/NMail.ImapService/State/AuthenticatedState.cs
NMail/trunk/NMail.ImapService/State/ExamineState.cs
NMail/trunk/NMail.ImapService/State/SelectedState.cs
NMail/trunk/NMail.LocalStore/DeliveryActions/ManageWhiteList.cs
NMail/trunk/NMail.LocalStore/LocalStore.cs
NMail/trunk/NMail.LocalStoreData.MySql/MySqlAuthProvider.cs
NMail/trunk/NMail.LocalStoreData.MySql/MySqlLocalStoreData.cs
NMail/trunk/NMail.LocalStoreData.NHibernate/InternalMessage.cs
NMail/trunk/NMail.LocalStoreData.NHibernate/Mappings/NMail.LocalStoreData.NHibernate.InternalMessage.hbm.xml
NMail/trunk/NMail.LocalStoreData.NHibernate/NHibernateAuthProvider.cs
NMail/trunk/NMail.LocalStoreData.NHibernate/NHibernateLocalStoreData.cs
NMail/trunk/NMail.LocalStoreData.NHibernate/NMail.LocalStoreData.NHibernate.csproj
NMail/trunk/NMail.MessageRouter/MessageRouter.cs
NMail/trunk/NMail.RemoteAccessService.Serializers/DataTypes/BodyStructureSerializer.cs
NMail/trunk/NMail.RemoteAccessService.Serializers/DataTypes/EnvelopeSerializer.cs
NMail/trunk/NMail.RemoteAccessService.Serializers/DataTypes/MessageHeadersSerializer.cs
NMail/trunk/NMail.Sendmail/Sendmail.cs
NMail/trunk/NMail.SmtpClient/SmtpClientConnection.cs
NMail/trunk/NMail.SmtpService/Command/DataCommand.cs
NMail/trunk/NMail.SpoolData.MySql/MySqlSpoolData.cs
NMail/trunk/NMail.UnitTests/DataTypes/MessageHeaderTests.cs
NMail/trunk/NMail.UnitTests/LocalStoreData/DeliverMessageTest1.cs
NMail/trunk/NMail.UnitTests/LocalStoreData/GetMessageIdTest1.cs
NMail/trunk/NMail.UnitTests/LocalStoreData/GetMessageIdsTest1.cs
NMail/trunk/NMail.UnitTests/LocalStoreData/GetMessageOffsetTest1.cs
NMail/trunk/NMail.UnitTests/LocalStoreData/GetNextMessageIdTest1.cs
NMail/trunk/NMail.UnitTests/LocalStoreData/GetSetMessageFlagsTest1.cs
NMail/trunk/NMail.UnitTests/NMail.UnitTests.csproj
NMail/trunk/NMail.UnitTests/Resources/ResourceHelper.cs
Added Paths:
-----------
NMail/trunk/NMail/DataTypes/Message/
NMail/trunk/NMail/DataTypes/Message/BodyStructure.cs
NMail/trunk/NMail/DataTypes/Message/Envelope.cs
NMail/trunk/NMail/DataTypes/Message/IMessageBodyPart.cs
NMail/trunk/NMail/DataTypes/Message/IMessagePart.cs
NMail/trunk/NMail/DataTypes/Message/IMultipartMessageBody.cs
NMail/trunk/NMail/DataTypes/Message/Message.cs
NMail/trunk/NMail/DataTypes/Message/MessageDataPart.cs
NMail/trunk/NMail/DataTypes/Message/MessageHeaders.cs
NMail/trunk/NMail/DataTypes/Message/MultipartMessageBody.cs
NMail/trunk/NMail/DataTypes/Message/SimpleMessageBody.cs
NMail/trunk/NMail.LocalStoreData.NHibernate/AuthenticationUser.cs
NMail/trunk/NMail.LocalStoreData.NHibernate/InternalSystemAce.cs
NMail/trunk/NMail.LocalStoreData.NHibernate/InternalUserObject.cs
NMail/trunk/NMail.LocalStoreData.NHibernate/Mappings/NMail.Authentication.BasicAuthToken.hbm.xml
NMail/trunk/NMail.LocalStoreData.NHibernate/Mappings/NMail.LocalStoreData.NHibernate.AuthenticationUser.hbm.xml
NMail/trunk/NMail.LocalStoreData.NHibernate/Mappings/NMail.LocalStoreData.NHibernate.InternalSystemAce.hbm.xml
NMail/trunk/NMail.LocalStoreData.NHibernate/Mappings/NMail.LocalStoreData.NHibernate.InternalUserObject.hbm.xml
NMail/trunk/NMail.UnitTests/LocalStoreData/DeliverMessageTest2.cs
NMail/trunk/NMail.UnitTests/LocalStoreData/GetMessageCountTest1.cs
NMail/trunk/NMail.UnitTests/LocalStoreData/GetMessageCountWithFlagsTest1.cs
NMail/trunk/NMail.UnitTests/LocalStoreData/GetMessageDateTest1.cs
NMail/trunk/NMail.UnitTests/LocalStoreData/GetMessageHeadersTest1.cs
NMail/trunk/NMail.UnitTests/LocalStoreData/GetMessageMimePartTest1.cs
NMail/trunk/NMail.UnitTests/LocalStoreData/GetMessageMimePartTest2.cs
NMail/trunk/NMail.UnitTests/LocalStoreData/GetMessageSizeTest1.cs
NMail/trunk/NMail.UnitTests/LocalStoreData/GetMessageTest1.cs
NMail/trunk/NMail.UnitTests/LocalStoreData/LoadSaveObjectTest1.cs
NMail/trunk/NMail.UnitTests/LocalStoreData/PurgeDeletedMessagesTest1.cs
NMail/trunk/NMail.UnitTests/Resources/Test2.eml
Removed Paths:
-------------
NMail/trunk/NMail/DataTypes/BodyStructure.cs
NMail/trunk/NMail/DataTypes/Envelope.cs
NMail/trunk/NMail/DataTypes/IMessageBodyPart.cs
NMail/trunk/NMail/DataTypes/IMessagePart.cs
NMail/trunk/NMail/DataTypes/Message.cs
NMail/trunk/NMail/DataTypes/MessageDataPart.cs
NMail/trunk/NMail/DataTypes/MessageHeaders.cs
NMail/trunk/NMail/DataTypes/MultipartBodyPart.cs
NMail/trunk/NMail/DataTypes/SimpleBodyPart.cs
Modified: NMail/trunk/NMail/Authentication/BasicAuthToken.cs
===================================================================
--- NMail/trunk/NMail/Authentication/BasicAuthToken.cs 2007-04-24 15:46:35 UTC (rev 186)
+++ NMail/trunk/NMail/Authentication/BasicAuthToken.cs 2007-04-30 08:59:18 UTC (rev 187)
@@ -24,6 +24,11 @@
[Serializable]
public class BasicAuthToken : IAuthenticationToken {
/// <summary>
+ /// Creates a new basic authentication token.
+ /// </summary>
+ public BasicAuthToken() { }
+
+ /// <summary>
/// Creates a new basic authentication token with the given username.
/// </summary>
/// <param name="username">The username associated with then authentication token.</param>
@@ -73,5 +78,56 @@
get { return tokenExpiry; }
}
#endregion
+
+ #region Comparison
+ /// <summary>
+ /// Checks if two tokens are equal.
+ /// </summary>
+ /// <param name="other">The token to compare.</param>
+ /// <returns>True if the token names match.</returns>
+ public override bool Equals(object other) {
+ return (other is BasicAuthToken) && this == (BasicAuthToken) other;
+ }
+
+ /// <summary>
+ /// Gets the unique hash code for this object.
+ /// </summary>
+ /// <returns>The hash code.</returns>
+ public override int GetHashCode() {
+ return base.GetHashCode();
+ }
+
+ /// <summary>
+ /// Checks if the given token is equal to this host.
+ /// </summary>
+ /// <param name="tokenA">Token A.</param>
+ /// <param name="tokenB">Token B.</param>
+ /// <returns>True if they are equal.</returns>
+ public static bool operator ==(BasicAuthToken tokenA, BasicAuthToken tokenB) {
+ if ((object) tokenA == null && (object) tokenB == null) {
+ return true;
+ }
+
+ if ((object) tokenA == null || (object) tokenB == null) {
+ return false;
+ }
+
+ return
+ (tokenA.username == tokenB.username) &&
+ (tokenA.tokenId == tokenB.tokenId) &&
+ (tokenA.tokenExpiry == tokenB.tokenExpiry) &&
+ (tokenA.credentialsExpiry == tokenB.credentialsExpiry);
+ }
+
+ /// <summary>
+ /// Checks if the given token is equal to this token.
+ /// </summary>
+ /// <param name="tokenA">Token A.</param>
+ /// <param name="tokenB">Token B.</param>
+ /// <returns>True if they are not equal.</returns>
+ public static bool operator !=(BasicAuthToken tokenA, BasicAuthToken tokenB) {
+ return !(tokenA == tokenB);
+ }
+ #endregion
}
}
Modified: NMail/trunk/NMail/Authentication/IAuthenticationProvider.cs
===================================================================
--- NMail/trunk/NMail/Authentication/IAuthenticationProvider.cs 2007-04-24 15:46:35 UTC (rev 186)
+++ NMail/trunk/NMail/Authentication/IAuthenticationProvider.cs 2007-04-30 08:59:18 UTC (rev 187)
@@ -46,20 +46,6 @@
IAuthenticationToken CreateAuthToken(string username);
/// <summary>
- /// Gets the date and time that the given token will expire.
- /// </summary>
- /// <param name="user">The token to check the expire time for.</param>
- /// <returns>The expiry time.</returns>
- DateTime GetTokenExpiry(IAuthenticationToken user);
-
- /// <summary>
- /// Checks if the given token has expired.
- /// </summary>
- /// <param name="user">The token to check the expire time for.</param>
- /// <returns>True if the token has expired.</returns>
- bool TokenExpired(IAuthenticationToken user);
-
- /// <summary>
/// Checks if the given authentication token is valid.
/// </summary>
/// <param name="user">The token to check.</param>
Modified: NMail/trunk/NMail/DataTypes/ACLs/GenericAce.cs
===================================================================
--- NMail/trunk/NMail/DataTypes/ACLs/GenericAce.cs 2007-04-24 15:46:35 UTC (rev 186)
+++ NMail/trunk/NMail/DataTypes/ACLs/GenericAce.cs 2007-04-30 08:59:18 UTC (rev 187)
@@ -25,7 +25,13 @@
/// </summary>
[Serializable]
public class GenericAce<PrivilegeType> {
+
/// <summary>
+ /// Creates a new empty ACE.
+ /// </summary>
+ public GenericAce() {}
+
+ /// <summary>
/// Creates a new access control entry.
/// </summary>
/// <param name="identifier">The identifier to associated the ACE with.</param>
Modified: NMail/trunk/NMail/DataTypes/ACLs/SystemPrivilege.cs
===================================================================
--- NMail/trunk/NMail/DataTypes/ACLs/SystemPrivilege.cs 2007-04-24 15:46:35 UTC (rev 186)
+++ NMail/trunk/NMail/DataTypes/ACLs/SystemPrivilege.cs 2007-04-30 08:59:18 UTC (rev 187)
@@ -7,7 +7,7 @@
/// The possible privileges a user or group can have on the NMail system.
/// </summary>
[FlagsAttribute]
- public enum SystemPrivilege : uint {
+ public enum SystemPrivilege : int {
/// <summary>
/// No rights are granted.
/// </summary>
Deleted: NMail/trunk/NMail/DataTypes/BodyStructure.cs
===================================================================
--- NMail/trunk/NMail/DataTypes/BodyStructure.cs 2007-04-24 15:46:35 UTC (rev 186)
+++ NMail/trunk/NMail/DataTypes/BodyStructure.cs 2007-04-30 08:59:18 UTC (rev 187)
@@ -1,134 +0,0 @@
-/*
- * Copyright 2004-2006 Luke Quinane
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-using System;
-using System.Collections.Generic;
-using System.Text;
-
-using NMail.Helper;
-
-namespace NMail.DataTypes {
- /// <summary>
- /// Represents a the structure of a message body.
- /// </summary>
- [Serializable]
- public class BodyStructure : List<BodyStructure> {
-
- public BodyStructure(IMessageBodyPart bodyPart) {
- this.headers = bodyPart.Headers;
-
- if (bodyPart.MultipartBody) {
- foreach (IMessageBodyPart part in bodyPart.MimeParts) {
- this.Add(new BodyStructure(part));
- }
- } else {
- // Count the number of lines in the message body
- string bodyData = bodyPart.BodyData.ToString();
- int index = bodyData.IndexOf(Message.Terminator);
- while (index != -1) {
- this.bodyLineCount++;
- index = bodyData.IndexOf(Message.Terminator, index + 1);
- }
-
- this.bodyCharacterCount = bodyData.Length;
- this.size = bodyPart.Size;
- }
- }
-
- public BodyStructure(MessageHeaders headers) {
- this.headers = headers;
- }
-
- private MessageHeaders headers;
-
- /// <summary>
- /// The message headers associated with this level of the body structure.
- /// </summary>
- public MessageHeaders Headers {
- get { return headers; }
- set { headers = value; }
- }
-
- private int bodyLineCount;
-
- /// <summary>
- /// The number of lines in the message body. Only valid for bodystructures
- /// without multiple parts.
- /// </summary>
- public int BodyLineCount {
- get { return bodyLineCount; }
- set { bodyLineCount = value; }
- }
-
- private int bodyCharacterCount;
-
- /// <summary>
- /// The number of characters in the body. Only valid for bodystructures
- /// witout multiple parts.
- /// </summary>
- public int BodyCharacterCount {
- get { return bodyCharacterCount; }
- set { bodyCharacterCount = value; }
- }
-
- private int size;
-
- /// <summary>
- /// The size of this part in bytes.
- /// </summary>
- public int Size {
- get { return size; }
- set { size = value; }
- }
-
- public override string ToString() {
- if (this.Count > 0) {
- StringBuilder data = new StringBuilder();
- data.Append("(");
-
- foreach (BodyStructure child in this) {
- data.Append(child.ToString());
- }
-
- data.Append("\"MIXED\")");
- return data.ToString();
-
- } else {
- MimeContentTransferEncoding encoding = MimeHelper.GetTransferEncoding(this.headers);
- MimeContentType contentType = MimeHelper.GetContentType(this.headers);
- string charset = MimeHelper.GetCharacterSet(this.headers);
-
- string encodingStr = encoding.ToString().ToUpper();
- if (encoding == MimeContentTransferEncoding.EightBit) {
- encodingStr = "8bit";
- } else if (encoding == MimeContentTransferEncoding.SevenBit) {
- encodingStr = "7bit";
- }
-
- return string.Format("(\"{0}\" \"{1}\" (\"charset\" \"{2}\") {3} {4} \"{5}\" {6} {7} NIL NIL NIL)",
- contentType.ToString().ToLower(),
- "plain",
- charset,
- "NIL", // body-fld-id
- "NIL", // body-fld-desc
- encodingStr,
- this.bodyCharacterCount,
- this.bodyLineCount);
- }
- }
- }
-}
Deleted: NMail/trunk/NMail/DataTypes/Envelope.cs
===================================================================
--- NMail/trunk/NMail/DataTypes/Envelope.cs 2007-04-24 15:46:35 UTC (rev 186)
+++ NMail/trunk/NMail/DataTypes/Envelope.cs 2007-04-30 08:59:18 UTC (rev 187)
@@ -1,364 +0,0 @@
-/*
- * Copyright 2004-2006 Luke Quinane
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-using System;
-using System.Collections.Generic;
-using System.Text;
-
-using NMail.Helper;
-
-namespace NMail.DataTypes {
- /// <summary>
- /// A message envelope. This includes the From, To, Cc, Bcc, Subject
- /// </summary>
- [Serializable]
- public class Envelope {
-
- protected Envelope() { }
-
- /// <summary>
- /// Creates a new envelope from the message headers.
- /// </summary>
- /// <param name="messageHeaders">The headers containing the envelope information.</param>
- public Envelope(MessageHeaders messageHeaders) {
- // These fields should never be null
- this.from = messageHeaders["From"];
- this.date = messageHeaders["Date"];
- this.subject = messageHeaders["Subject"];
-
- this.sender = messageHeaders["Sender"];
- if (this.sender == null || this.sender.Trim() == string.Empty) {
- this.sender = this.from;
- }
- this.replyTo = messageHeaders["Rely-To"];
- if (this.replyTo == null || this.replyTo.Trim() == string.Empty) {
- this.replyTo = this.from;
- }
-
- // These fields can be null
- this.messageId = messageHeaders["Message-Id"];
- if (this.messageId != null && this.messageId.Trim() == string.Empty) {
- this.messageId = null;
- }
- this.to = messageHeaders["To"];
- if (this.to != null && this.to.Trim() == string.Empty) {
- this.to = null;
- }
- this.inReplyTo = messageHeaders["In-Reply-To"];
- if (this.inReplyTo != null && this.inReplyTo.Trim() == string.Empty) {
- this.inReplyTo = null;
- }
- this.bcc = messageHeaders["Bcc"];
- if (this.bcc != null && this.inReplyTo.Trim() == string.Empty) {
- this.bcc = null;
- }
- this.cc = messageHeaders["Cc"];
- if (this.cc != null && this.cc.Trim() == string.Empty) {
- this.cc = null;
- }
- }
-
- /// <summary>
- /// Creates a new envelope with the minimum required fields.
- /// </summary>
- /// <param name="from">The sender of the message.</param>
- /// <param name="date">The date the message was sent.</param>
- /// <param name="subject">The message's subject.</param>
- public Envelope(string from, string date, string subject) {
- this.from = from;
- this.sender = from;
- this.replyTo = from;
-
- this.subject = subject;
- this.date = date;
- }
-
- #region Properties
-
- private string messageId;
-
- /// <summary>
- /// Extracted from the Message-Id header.
- /// </summary>
- public string MessageId {
- get {
- return this.messageId;
- }
- set {
- this.messageId = value;
- }
- }
-
- private string from;
-
- /// <summary>
- /// The value extracted from the From header field.
- /// </summary>
- public string From {
- get {
- return this.from;
- }
- set {
- this.from = value;
- }
- }
-
- private string sender;
-
- /// <summary>
- /// The value extracted from the Sender header field.
- /// </summary>
- public string Sender {
- get {
- return this.sender;
- }
- set {
- this.sender = value;
- }
- }
-
- private string to;
-
- /// <summary>
- /// The value extracted from the To header field.
- /// </summary>
- public string To {
- get {
- return this.to;
- }
- set {
- this.to = value;
- }
- }
-
-
- private string inReplyTo;
-
- /// <summary>
- /// The value extracted from the In-Reply-To header field.
- /// </summary>
- public string InReplyTo {
- get {
- return this.inReplyTo;
- }
- set {
- this.inReplyTo = value;
- }
- }
-
-
- private string replyTo;
-
- /// <summary>
- /// The value extracted from the Reply-To header field.
- /// </summary>
- public string ReplyTo {
- get {
- return this.replyTo;
- }
- set {
- this.replyTo = value;
- }
- }
-
-
- private string bcc;
-
- /// <summary>
- /// The value extracted from the Bcc header field.
- /// </summary>
- public string Bcc {
- get {
- return this.bcc;
- }
- set {
- this.bcc = value;
- }
- }
-
-
- private string cc;
-
- /// <summary>
- /// The value extracted from the Cc header field.
- /// </summary>
- public string Cc {
- get {
- return this.cc;
- }
- set {
- this.cc = value;
- }
- }
-
-
- private string subject;
-
- /// <summary>
- /// The value extracted from the Subject header field.
- /// </summary>
- public string Subject {
- get {
- return this.subject;
- }
- set {
- this.subject = value;
- }
- }
-
-
- private string date;
-
- /// <summary>
- /// The value extracted from the Date header field.
- /// </summary>
- public string Date {
- get {
- return this.date;
- }
- set {
- this.date = value;
- }
- }
- #endregion
-
- #region getEnvelopeImapAddress
- private string getEnvelopeImapAddress(string data) {
- // TODO: handle groups
-
- StringBuilder output = new StringBuilder();
- string[] addresses = StringTokenizer.GetQuotedTokens(data, ",".ToCharArray(), Int32.MaxValue, false);
-
- output.Append("(");
-
- foreach (string address in addresses) {
- string[] tokens = StringTokenizer.GetQuotedTokens(address, " ".ToCharArray(), Int32.MaxValue, true);
- string emailAddress = null;
- string personalName = null;
- string host = null;
- string mailbox = null;
-
- if (tokens.Length > 0) {
- if (tokens[0][0] != '<') {
- personalName = tokens[0];
-
- if (tokens.Length > 1) {
- emailAddress = tokens[1];
- }
- } else {
- // No personal name
- emailAddress = tokens[0];
- }
- }
-
- if (emailAddress != null) {
- try {
- EmailAddress tmpAddress = new EmailAddress(emailAddress, true);
- host = tmpAddress.Host.ToString();
- mailbox = tmpAddress.Mailbox.ToString();
- } catch {
- }
- }
-
- // Append the personal name and source route
- if (personalName != null) {
- output.Append("(\"");
- output.Append(personalName);
- output.Append("\" NIL ");
- } else {
- output.Append("(NIL NIL ");
- }
-
- // Append the mailbox
- if (mailbox != null) {
- output.Append("\"");
- output.Append(mailbox);
- output.Append("\" ");
- } else {
- output.Append("NIL ");
- }
-
- // Append the host
- if (host != null) {
- output.Append("\"");
- output.Append(host);
- output.Append("\")");
- } else {
- output.Append("NIL)");
- }
- }
-
- output.Append(")");
-
- return output.ToString();
- }
- #endregion
-
- #region ToImapEnvelopeString
- /// <summary>
- /// Converts this envelope into a string that can be used in an IMAP envelope
- /// response.
- /// </summary>
- /// <returns>The IMAP envelope string.</returns>
- public string ToImapEnvelopeString() {
- StringBuilder envelope = new StringBuilder();
-
- envelope.Append("ENVELOPE (\"");
- envelope.Append(this.date);
- envelope.Append("\" \"");
- envelope.Append(this.subject);
- envelope.Append("\" ");
-
- // From
- envelope.Append(getEnvelopeImapAddress(this.from));
- envelope.Append(" ");
-
- // Sender
- envelope.Append(getEnvelopeImapAddress(this.sender));
- envelope.Append(" ");
-
- // Reply-To
- envelope.Append(getEnvelopeImapAddress(this.replyTo));
- envelope.Append(" ");
-
- // To
- envelope.Append((this.to == null) ? "NIL" : getEnvelopeImapAddress(this.to));
- envelope.Append(" ");
-
- // Cc
- envelope.Append((this.cc == null) ? "NIL" : getEnvelopeImapAddress(this.cc));
- envelope.Append(" ");
-
- // Bcc
- envelope.Append((this.bcc == null) ? "NIL" : getEnvelopeImapAddress(this.bcc));
- envelope.Append(" ");
-
- // In-Reply-To
- envelope.Append("\"");
- envelope.Append((this.inReplyTo == null) ? "NIL" : this.inReplyTo);
- envelope.Append("\" ");
-
- // Message-Id
- envelope.Append("\"");
- envelope.Append((this.messageId == null) ? "NIL" : this.messageId);
- envelope.Append("\")");
-
- return envelope.ToString();
- }
- #endregion
- }
-}
Deleted: NMail/trunk/NMail/DataTypes/IMessageBodyPart.cs
===================================================================
--- NMail/trunk/NMail/DataTypes/IMessageBodyPart.cs 2007-04-24 15:46:35 UTC (rev 186)
+++ NMail/trunk/NMail/DataTypes/IMessageBodyPart.cs 2007-04-30 08:59:18 UTC (rev 187)
@@ -1,56 +0,0 @@
-/*
- * Copyright 2004-2006 Luke Quinane and Daniel Frampton
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-using System;
-using System.Collections.Generic;
-
-namespace NMail.DataTypes {
- /// <summary>
- /// A body part of a RFC 2822 message.
- /// </summary>
- public interface IMessageBodyPart : IMessagePart {
- /// <summary>
- /// Gets or sets the headers associated with this body part.
- /// </summary>
- MessageHeaders Headers { get; set; }
-
- /// <summary>
- /// The data for the body of this body part.
- /// </summary>
- ByteString BodyData { get; }
-
- /// <summary>
- /// Checks if the current body part is a multi-part body.
- /// </summary>
- bool MultipartBody { get; }
-
- /// <summary>
- /// Gets the mime parts of this message part, if any.
- /// </summary>
- IList<IMessageBodyPart> MimeParts { get; }
-
- /// <summary>
- /// Gets the preamble for the message body, if any.
- /// </summary>
- IMessagePart Preamble { get; }
-
- /// <summary>
- /// Gets the postamble for the message body, if any.
- /// </summary>
- IMessagePart Postamble { get; }
- }
-}
Deleted: NMail/trunk/NMail/DataTypes/IMessagePart.cs
===================================================================
--- NMail/trunk/NMail/DataTypes/IMessagePart.cs 2007-04-24 15:46:35 UTC (rev 186)
+++ NMail/trunk/NMail/DataTypes/IMessagePart.cs 2007-04-30 08:59:18 UTC (rev 187)
@@ -1,35 +0,0 @@
-/*
- * Copyright 2004-2006 Luke Quinane and Daniel Frampton
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-using System;
-
-namespace NMail.DataTypes {
- /// <summary>
- /// A part of a RFC 2822 message.
- /// </summary>
- public interface IMessagePart {
- /// <summary>
- /// The data as a single string.
- /// </summary>
- ByteString Data { get; }
-
- /// <summary>
- /// The size of the data in bytes.
- /// </summary>
- int Size { get; }
- }
-}
Modified: NMail/trunk/NMail/DataTypes/LocalStore/ILocalStore.cs
===================================================================
--- NMail/trunk/NMail/DataTypes/LocalStore/ILocalStore.cs 2007-04-24 15:46:35 UTC (rev 186)
+++ NMail/trunk/NMail/DataTypes/LocalStore/ILocalStore.cs 2007-04-30 08:59:18 UTC (rev 187)
@@ -22,6 +22,7 @@
using NMail.DataTypes;
using NMail.DataTypes.ACLs;
using NMail.DataTypes.Calendar;
+using NMail.DataTypes.Message;
namespace NMail.DataTypes.LocalStore {
/// <summary>
@@ -64,7 +65,7 @@
/// <param name="message">The message to deliver.</param>
/// <param name="folder">The folder to deliver the message into.</param>
/// <returns>The result of the delivery.</returns>
- DeliveryResult DeliverMessage(IAuthenticationToken authToken, Message message, StoreFolder folder);
+ DeliveryResult DeliverMessage(IAuthenticationToken authToken, Message.Message message, StoreFolder folder);
#endregion
#region Folder Retrieval and Manipulation
@@ -291,7 +292,7 @@
/// <param name="messageId">The Id of the message to get.</param>
/// <param name="folderId">The Id of the folder the message is in.</param>
/// <returns>The message or null if the message Id is invalid.</returns>
- Message GetMessage(IAuthenticationToken authToken, int messageId, int folderId);
+ Message.Message GetMessage(IAuthenticationToken authToken, int messageId, int folderId);
/// <summary>
/// Gets the body structure for a message.
Modified: NMail/trunk/NMail/DataTypes/LocalStore/ILocalStoreData.cs
===================================================================
--- NMail/trunk/NMail/DataTypes/LocalStore/ILocalStoreData.cs 2007-04-24 15:46:35 UTC (rev 186)
+++ NMail/trunk/NMail/DataTypes/LocalStore/ILocalStoreData.cs 2007-04-30 08:59:18 UTC (rev 187)
@@ -22,6 +22,7 @@
using NMail.DataTypes;
using NMail.DataTypes.ACLs;
using NMail.DataTypes.Calendar;
+using NMail.DataTypes.Message;
namespace NMail.DataTypes.LocalStore {
/// <summary>
@@ -47,7 +48,8 @@
/// </summary>
/// <param name="message">The message data.</param>
/// <param name="folder">The Id of the folder to deliver into.</param>
- void DeliverMessage(Message message, int folderId);
+ /// <exception cref="ArgumentException">The folder Id was invalid.</exception>
+ void DeliverMessage(Message.Message message, int folderId);
#endregion
#region Folder Retrieval and Manipulation
@@ -209,24 +211,24 @@
/// Gets the internal date for the message.
/// </summary>
/// <param name="messageId">The Id of the message to get the date for.</param>
- /// <param name="folder">The folder the message is in.</param>
- /// <returns>The message date.</returns>
- DateTime GetInternalDate(int messageId, StoreFolder folder);
+ /// <param name="folderId">The Id of the folder the message is in.</param>
+ /// <returns>The message date or null if non is found.</returns>
+ DateTime? GetInternalDate(int messageId, int folderId);
/// <summary>
/// Gets the size of the message.
/// </summary>
/// <param name="messageId">The Id of the message to get the size from.</param>
- /// <param name="folder">The folder the message is in.</param>
- /// <returns>The message size in bytes.</returns>
- int GetMessageSize(int messageId, StoreFolder folder);
+ /// <param name="folderId">The Id of the folder the message is in.</param>
+ /// <returns>The message size in bytes or null if non is found.</returns>
+ int? GetMessageSize(int messageId, int folderId);
/// <summary>
/// Gets the headers for the message.
/// </summary>
/// <param name="messageId">The Id of the message to get the headers for.</param>
/// <param name="folderId">The Id of the folder the message is in.</param>
- /// <returns>The message headers or null if none exist.</returns>
+ /// <returns>The message headers or null if none exists.</returns>
MessageHeaders GetMessageHeaders(int messageId, int folderId);
/// <summary>
@@ -244,7 +246,7 @@
/// <param name="messageId">The Id of the message to get.</param>
/// <param name="folderId">The Id of the folder the message is in.</param>
/// <returns>The message or null if the message Id is invalid.</returns>
- Message GetMessage(int messageId, int folderId);
+ Message.Message GetMessage(int messageId, int folderId);
#endregion
#region Message Counts
@@ -258,18 +260,18 @@
/// <summary>
/// Gets the number of messages with the specified flag set.
/// </summary>
- /// <param name="folder">The folder to count the flagged messages in.</param>
+ /// <param name="folderId">The Id of the folder to count the flagged messages in.</param>
/// <param name="flags">The flags to check for when counting.</param>
/// <returns>The number of messages.</returns>
- int GetMessageCountWithFlags(StoreFolder folder, StoreMessageFlags flags);
+ int GetMessageCountWithFlags(int folderId, StoreMessageFlags flags);
#endregion
/// <summary>
/// Permanently removes messages flagged as deleted.
/// </summary>
- /// <param name="folder">The folder to delete messages in.</param>
+ /// <param name="folderId">The Id of the folder to delete messages in.</param>
/// <returns>The list of message offsets for the deleted messages.</returns>
- int[] PurgeDeletedMessages(StoreFolder folder);
+ IList<int> PurgeDeletedMessages(int folderId);
#region Load and Save Object
/// <summary>
Modified: NMail/trunk/NMail/DataTypes/LocalStore/LocalStoreDelivery.cs
===================================================================
--- NMail/trunk/NMail/DataTypes/LocalStore/LocalStoreDelivery.cs 2007-04-24 15:46:35 UTC (rev 186)
+++ NMail/trunk/NMail/DataTypes/LocalStore/LocalStoreDelivery.cs 2007-04-30 08:59:18 UTC (rev 187)
@@ -39,7 +39,7 @@
this.additionalFolders = new ArrayList();
}
- public LocalStoreDelivery(Message message, Folder nominalTargetFolder) {
+ public LocalStoreDelivery(Message.Message message, Folder nominalTargetFolder) {
this.message = message;
this.folderDelimiter = NMailConfiguration.Current.LocalStore.FolderDelimiter;
@@ -88,12 +88,12 @@
}
}
- private Message message;
+ private Message.Message message;
/// <summary>
/// Gets the message associated with this instance.
/// </summary>
- public Message Message {
+ public Message.Message Message {
get {
return this.message;
}
Added: NMail/trunk/NMail/DataTypes/Message/BodyStructure.cs
===================================================================
--- NMail/trunk/NMail/DataTypes/Message/BodyStructure.cs (rev 0)
+++ NMail/trunk/NMail/DataTypes/Message/BodyStructure.cs 2007-04-30 08:59:18 UTC (rev 187)
@@ -0,0 +1,134 @@
+/*
+ * Copyright 2004-2006 Luke Quinane
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+using NMail.Helper;
+
+namespace NMail.DataTypes.Message {
+ /// <summary>
+ /// Represents a the structure of a message body.
+ /// </summary>
+ [Serializable]
+ public class BodyStructure : List<BodyStructure> {
+
+ public BodyStructure(IMessageBodyPart bodyPart) {
+ this.headers = bodyPart.Headers;
+
+ if (bodyPart is IMultipartMessageBody) {
+ foreach (IMessageBodyPart part in ((IMultipartMessageBody) bodyPart).MimeParts) {
+ this.Add(new BodyStructure(part));
+ }
+ } else {
+ // Count the number of lines in the message body
+ string bodyData = bodyPart.BodyData.ToString();
+ int index = bodyData.IndexOf(Message.Terminator);
+ while (index != -1) {
+ this.bodyLineCount++;
+ index = bodyData.IndexOf(Message.Terminator, index + 1);
+ }
+
+ this.bodyCharacterCount = bodyData.Length;
+ this.size = bodyPart.Size;
+ }
+ }
+
+ public BodyStructure(MessageHeaders headers) {
+ this.headers = headers;
+ }
+
+ private MessageHeaders headers;
+
+ /// <summary>
+ /// The message headers associated with this level of the body structure.
+ /// </summary>
+ public MessageHeaders Headers {
+ get { return headers; }
+ set { headers = value; }
+ }
+
+ private int bodyLineCount;
+
+ /// <summary>
+ /// The number of lines in the message body. Only valid for bodystructures
+ /// without multiple parts.
+ /// </summary>
+ public int BodyLineCount {
+ get { return bodyLineCount; }
+ set { bodyLineCount = value; }
+ }
+
+ private int bodyCharacterCount;
+
+ /// <summary>
+ /// The number of characters in the body. Only valid for bodystructures
+ /// witout multiple parts.
+ /// </summary>
+ public int BodyCharacterCount {
+ get { return bodyCharacterCount; }
+ set { bodyCharacterCount = value; }
+ }
+
+ private int size;
+
+ /// <summary>
+ /// The size of this part in bytes.
+ /// </summary>
+ public int Size {
+ get { return size; }
+ set { size = value; }
+ }
+
+ public string ToImapString() {
+ if (this.Count > 0) {
+ StringBuilder data = new StringBuilder();
+ data.Append("(");
+
+ foreach (BodyStructure child in this) {
+ data.Append(child.ToString());
+ }
+
+ data.Append("\"MIXED\")");
+ return data.ToString();
+
+ } else {
+ MimeContentTransferEncoding encoding = MimeHelper.GetTransferEncoding(this.headers);
+ MimeContentType contentType = MimeHelper.GetContentType(this.headers);
+ string charset = MimeHelper.GetCharacterSet(this.headers);
+
+ string encodingStr = encoding.ToString().ToUpper();
+ if (encoding == MimeContentTransferEncoding.EightBit) {
+ encodingStr = "8bit";
+ } else if (encoding == MimeContentTransferEncoding.SevenBit) {
+ encodingStr = "7bit";
+ }
+
+ return string.Format("(\"{0}\" \"{1}\" (\"charset\" \"{2}\") {3} {4} \"{5}\" {6} {7} NIL NIL NIL)",
+ contentType.ToString().ToLower(),
+ "plain",
+ charset,
+ "NIL", // body-fld-id
+ "NIL", // body-fld-desc
+ encodingStr,
+ this.bodyCharacterCount,
+ this.bodyLineCount);
+ }
+ }
+ }
+}
Added: NMail/trunk/NMail/DataTypes/Message/Envelope.cs
===================================================================
--- NMail/trunk/NMail/DataTypes/Message/Envelope.cs (rev 0)
+++ NMail/trunk/NMail/DataTypes/Message/Envelope.cs 2007-04-30 08:59:18 UTC (rev 187)
@@ -0,0 +1,364 @@
+/*
+ * Copyright 2004-2006 Luke Quinane
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+using NMail.Helper;
+
+namespace NMail.DataTypes.Message {
+ /// <summary>
+ /// A message envelope. This includes the From, To, Cc, Bcc, Subject
+ /// </summary>
+ [Serializable]
+ public class Envelope {
+
+ protected Envelope() { }
+
+ /// <summary>
+ /// Creates a new envelope from the message headers.
+ /// </summary>
+ /// <param name="messageHeaders">The headers containing the envelope information.</param>
+ public Envelope(MessageHeaders messageHeaders) {
+ // These fields should never be null
+ this.from = messageHeaders["From"];
+ this.date = messageHeaders["Date"];
+ this.subject = messageHeaders["Subject"];
+
+ this.sender = messageHeaders["Sender"];
+ if (this.sender == null || this.sender.Trim() == string.Empty) {
+ this.sender = this.from;
+ }
+ this.replyTo = messageHeaders["Rely-To"];
+ if (this.replyTo == null || this.replyTo.Trim() == string.Empty) {
+ this.replyTo = this.from;
+ }
+
+ // These fields can be null
+ this.messageId = messageHeaders["Message-Id"];
+ if (this.messageId != null && this.messageId.Trim() == string.Empty) {
+ this.messageId = null;
+ }
+ this.to = messageHeaders["To"];
+ if (this.to != null && this.to.Trim() == string.Empty) {
+ this.to = null;
+ }
+ this.inReplyTo = messageHeaders["In-Reply-To"];
+ if (this.inReplyTo != null && this.inReplyTo.Trim() == string.Empty) {
+ this.inReplyTo = null;
+ }
+ this.bcc = messageHeaders["Bcc"];
+ if (this.bcc != null && this.inReplyTo.Trim() == string.Empty) {
+ this.bcc = null;
+ }
+ this.cc = messageHeaders["Cc"];
+ if (this.cc != null && this.cc.Trim() == string.Empty) {
+ this.cc = null;
+ }
+ }
+
+ /// <summary>
+ /// Creates a new envelope with the minimum required fields.
+ /// </summary>
+ /// <param name="from">The sender of the message.</param>
+ /// <param name="date">The date the message was sent.</param>
+ /// <param name="subject">The message's subject.</param>
+ public Envelope(string from, string date, string subject) {
+ this.from = from;
+ this.sender = from;
+ this.replyTo = from;
+
+ this.subject = subject;
+ this.date = date;
+ }
+
+ #region Properties
+
+ private string messageId;
+
+ /// <summary>
+ /// Extracted from the Message-Id header.
+ /// </summary>
+ public string MessageId {
+ get {
+ return this.messageId;
+ }
+ set {
+ this.messageId = value;
+ }
+ }
+
+ private string from;
+
+ /// <summary>
+ /// The value extracted from the From header field.
+ /// </summary>
+ public string From {
+ get {
+ return this.from;
+ }
+ set {
+ this.from = value;
+ }
+ }
+
+ private string sender;
+
+ /// <summary>
+ /// The value extracted from the Sender header field.
+ /// </summary>
+ public string Sender {
+ get {
+ return this.sender;
+ }
+ set {
+ this.sender = value;
+ }
+ }
+
+ private string to;
+
+ /// <summary>
+ /// The value extracted from the To header field.
+ /// </summary>
+ public string To {
+ get {
+ return this.to;
+ }
+ set {
+ this.to = value;
+ }
+ }
+
+
+ private string inReplyTo;
+
+ /// <summary>
+ /// The value extracted from the In-Reply-To header field.
+ /// </summary>
+ public string InReplyTo {
+ get {
+ return this.inReplyTo;
+ }
+ set {
+ this.inReplyTo = value;
+ }
+ }
+
+
+ private string replyTo;
+
+ /// <summary>
+ /// The value extracted from the Reply-To header field.
+ /// </summary>
+ public string ReplyTo {
+ get {
+ return this.replyTo;
+ }
+ set {
+ this.replyTo = value;
+ }
+ }
+
+
+ private string bcc;
+
+ /// <summary>
+ /// The value extracted from the Bcc header field.
+ /// </summary>
+ public string Bcc {
+ get {
+ return this.bcc;
+ }
+ set {
+ this.bcc = value;
+ }
+ }
+
+
+ private string cc;
+
+ /// <summary>
+ /// The value extracted from the Cc header field.
+ /// </summary>
+ public string Cc {
+ get {
+ return this.cc;
+ }
+ set {
+ this.cc = value;
+ }
+ }
+
+
+ private string subject;
+
+ /// <summary>
+ /// The value extracted from the Subject header field.
+ /// </summary>
+ public string Subject {
+ get {
+ return this.subject;
+ }
+ set {
+ this.subject = value;
+ }
+ }
+
+
+ private string date;
+
+ /// <summary>
+ /// The value extracted from the Date header field.
+ /// </summary>
+ public string Date {
+ get {
+ return this.date;
+ }
+ set {
+ this.date = value;
+ }
+ }
+ #endregion
+
+ #region getEnvelopeImapAddress
+ private string getEnvelopeImapAddress(string data) {
+ // TODO: handle groups
+
+ StringBuilder output = new StringBuilder();
+ string[] addresses = StringTokenizer.GetQuotedTokens(data, ",".ToCharArray(), Int32.MaxValue, false);
+
+ output.Append("(");
+
+ foreach (string address in addresses) {
+ string[] tokens = StringTokenizer.GetQuotedTokens(address, " ".ToCharArray(), Int32.MaxValue, true);
+ string emailAddress = null;
+ string personalName = null;
+ string host = null;
+ string mailbox = null;
+
+ if (tokens.Length > 0) {
+ if (tokens[0][0] != '<') {
+ personalName = tokens[0];
+
+ if (tokens.Length > 1) {
+ emailAddress = tokens[1];
+ }
+ } else {
+ // No personal name
+ emailAddress = tokens[0];
+ }
+ }
+
+ if (emailAddress != null) {
+ try {
+ EmailAddress tmpAddress = new EmailAddress(emailAddress, true);
+ host = tmpAddress.Host.ToString();
+ mailbox = tmpAddress.Mailbox.ToString();
+ } catch {
+ }
+ }
+
+ // Append the personal name and source route
+ if (personalName != null) {
+ output.Append("(\"");
+ output.Append(personalName);
+ output.Append("\" NIL ");
+ } else {
+ output.Append("(NIL NIL ");
+ }
+
+ // Append the mailbox
+ if (mailbox != null) {
+ output.Append("\"");
+ output.Append(mailbox);
+ output.Append("\" ");
+ } else {
+ output.Append("NIL ");
+ }
+
+ // Append the host
+ if (host != null) {
+ output.Append("\"");
+ output.Append(host);
+ output.Append("\")");
+ } else {
+ output.Append("NIL)");
+ }
+ }
+
+ output.Append(")");
+
+ return output.ToString();
+ }
+ #endregion
+
+ #region ToImapEnvelopeString
+ /// <summary>
+ /// Converts this envelope into a string that can be used in an IMAP envelope
+ /// response.
+ /// </summary>
+ /// <returns>The IMAP envelope string.</returns>
+ public string ToImapEnvelopeString() {
+ StringBuilder envelope = new StringBuilder();
+
+ envelope.Append("ENVELOPE (\"");
+ envelope.Append(this.date);
+ envelope.Append("\" \"");
+ envelope.Append(this.subject);
+ envelope.Append("\" ");
+
+ // From
+ envelope.Append(getEnvelopeImapAddress(this.from));
+ envelope.Append(" ");
+
+ // Sender
+ envelope.Append(getEnvelopeImapAddress(this.sender));
+ envelope.Append(" ");
+
+ // Reply-To
+ envelope.Append(getEnvelopeImapAddress(this.replyTo));
+ envelope.Append(" ");
+
+ // To
+ envelope.Append((this.to == null) ? "NIL" : getEnvelopeImapAddress(this.to));
+ envelope.Append(" ");
+
+ // Cc
+ envelope.Append((this.cc == null) ? "NIL" : getEnvelopeImapAddress(this.cc));
+ envelope.Append(" ");
+
+ // Bcc
+ envelope.Append((this.bcc == null) ? "NIL" : getEnvelopeImapAddress(this.bcc));
+ envelope.Append(" ");
+
+ // In-Reply-To
+ envelope.Append("\"");
+ envelope.Append((this.inReplyTo == null) ? "NIL" : this.inReplyTo);
+ envelope.Append("\" ");
+
+ // Message-Id
+ envelope.Append("\"");
+ envelope.Append((this.messageId == null) ? "NIL" : this.messageId);
+ envelope.Append("\")");
+
+ return envelope.ToString();
+ }
+ #endregion
+ }
+}
Added: NMail/trunk/NMail/DataTypes/Message/IMessageBodyPart.cs
===================================================================
--- NMail/trunk/NMail/DataTypes/Message/IMessageBodyPart.cs (rev 0)
+++ NMail/trunk/NMail/DataTypes/Message/IMessageBodyPart.cs 2007-04-30 08:59:18 UTC (rev 187)
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2004-2006 Luke Quinane and Daniel Frampton
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+using System;
+using System.Collections.Generic;
+
+namespace NMail.DataTypes.Message {
+ /// <summary>
+ /// A body part of a RFC 2822 message.
+ /// </summary>
+ public interface IMessageBodyPart : IMessagePart {
+ /// <summary>
+ /// Gets or sets the headers associated with this body part.
+ /// </summary>
+ MessageHeaders Headers { get; set; }
+
+ /// <summary>
+ /// The data for the body of this body part.
+ /// </summary>
+ ByteString BodyData { get; }
+ }
+}
Added: NMail/trunk/NMail/DataTypes/Message/IMessagePart.cs
===================================================================
--- NMail/trunk/NMail/DataTypes/Message/IMessagePart.cs (rev 0)
+++ NMail/trunk/NMail/DataTypes/Message/IMessagePart.cs 2007-04-30 08:59:18 UTC (rev 187)
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2004-2006 Luke Quinane and Daniel Frampton
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+using System;
+
+namespace NMail.DataTypes.Message {
+ /// <summary>
+ /// A part of a RFC 2822 message.
+ /// </summary>
+ public interface IMessagePart {
+ /// <summary>
+ /// The data as a single string.
+ /// </summary>
+ ByteString Data { get; }
+
+ /// <summary>
+ /// The size of the data in bytes.
+ /// </summary>
+ int Size { get; }
+ }
+}
Added: NMail/trunk/NMail/DataTypes/Message/IMultipartMessageBody.cs
===================================================================
--- NMail/trunk/NMail/DataTypes/Message/IMultipartMessageBody.cs (rev 0)
+++ NMail/trunk/NMail/DataTypes/Message/IMultipartMessageBody.cs 2007-04-30 08:59:18 UTC (rev 187)
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2004-2007 Luke Quinane
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace NMail.DataTypes.Message {
+ public interface IMultipartMessageBody : IMessageBodyPart {
+ /// <summary>
+ /// Gets the mime parts of this message part, if any.
+ /// </summary>
+ IList<IMessageBodyPart> MimeParts { get; }
+
+ /// <summary>
+ /// Gets the preamble for the message body, if any.
+ /// </summary>
+ IMessagePart Preamble { get; set; }
+
+ /// <summary>
+ /// Gets the postamble for the message body, if any.
+ /// </summary>
+ IMessagePart Postamble { get; set; }
+
+ /// <summary>
+ /// A string containing the mime boundary.
+ /// </summary>
+ string MimeBoundary { get; set; }
+ }
+}
Added: NMail/trunk/NMail/DataTypes/Message/Message.cs
===================================================================
--- NMail/trunk/NMail/DataTypes/Message/Message.cs (rev 0)
+++ NMail/trunk/NMail/DataTypes/Message/Message.cs 2007-04-30 08:59:18 UTC (rev 187)
@@ -0,0 +1,157 @@
+/*
+ * Copyright 2004-2006 Luke Quinane and Daniel Frampton
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Collections.Specialized;
+using System.Text;
+using System.Text.RegularExpressions;
+
+using NMail.Helper;
+
+namespace NMail.DataTypes.Message {
+ /// <summary>
+ /// An RFC 2822 compliant message.
+ /// </summary>
+ [Serializable]
+ public class Message : IMessageBodyPart {
+ /// <summary>
+ /// Creates a new emtpy message.
+ /// </summary>
+ public Message() {
+ this.body = new SimpleMessageBody();
+ }
+
+ /// <summary>
+ /// Creates a message from the given data.
+ /// </summary>
+ /// <param name="data">The data to create the message from.</param>
+ public Message(ByteString data) {
+ this.body = MessageHelper.ParseMessage(data);
+ }
+
+ /// <summary>
+ /// Creates a message from the given data.
+ /// </summary>
+ /// <param name="dataString">The data to create the message from.</param>
+ public Message(string dataString) {
+ // TODO: check this encoding is ok
+ ByteString data = new ByteString(dataString, Encoding.ASCII);
+ this.body = MessageHelper.ParseMessage(data);
+ }
+
+ /// <summary>
+ /// Creates a new message from the given body data.
+ /// </summary>
+ /// <param name="bodyData">The data to use in the message.</param>
+ public Message(IMessageBodyPart bodyData) {
+ this.body = bodyData;
+ }
+
+ /// <summary>
+ /// Gets an envelope for this message.
+ /// </summary>
+ /// <returns>The envelope.</returns>
+ public Envelope GetEnvelope() {
+ return new Envelope(this.Headers);
+ }
+
+ /// <summary>
+ /// Converts the body to a multipart body.
+ /// </summary>
+ public void ConvertToMultipartBody() {
+ if (!(this.body is IMultipartMessageBody)) {
+ MessageDataPart preamble = null;
+ MessageDataPart postamble = null;
+ IMessageBodyPart[] parsedParts;
+
+ string mimeBoundary = MimeHelper.GetBoundary(this.body.Headers);
+
+ if (mimeBoundary != null) {
+ // Parse the MIME parts and pre/postambles
+ MimeHelper.ParseMime(
+ mimeBoundary,
+ this.body.BodyData,
+ out preamble,
+ out parsedParts,
+ out postamble);
+ } else {
+ parsedParts = new IMessageBodyPart[1];
+ parsedParts[0] = this.body;
+ }
+
+ this.body = new MultipartMessageBody(this.body.Headers, preamble, parsedParts, postamble);
+ }
+ }
+
+ private IMessageBodyPart body;
+
+ /// <summary>
+ /// The body data associated with this message
+ /// </summary>
+ public IMessageBodyPart Body {
+ get { return body; }
+ set { body = value; }
+ }
+
+ #region IMessageBodyPart
+ /// <summary>
+ /// Gets or sets the headers associated with this body part.
+ /// </summary>
+ public MessageHeaders Headers {
+ get {
+ return this.body.Headers;
+ }
+ set {
+ this.body.Headers = value;
+ }
+ }
+
+ /// <summary>
+ /// The data for the body of this body part.
+ /// </summary>
+ public ByteString BodyData {
+ get {
+ return this.body.BodyData;
+ }
+ }
+
+ /// <summary>
+ /// The data as a single string.
+ /// </summary>
+ public ByteString Data {
+ get {
+ return this.body.Data;
+ }
+ }
+
+ /// <summary>
+ /// The size of the data in bytes.
+ /// </summary>
+ public int Size {
+ get {
+ return this.body.Size;
+ }
+ }
+ #endregion
+
+ /// <summary>
+ /// The end of line terminator.
+ /// </summary>
+ public const string Terminator = "\r\n";
+ }
+}
Added: NMail/trunk/NMail/DataTypes/Message/MessageDataPart.cs
===================================================================
--- NMail/trunk/NMail/DataTypes/Message/MessageDataPart.cs (rev 0)
+++ NMail/trunk/NMail/DataTypes/Message/MessageDataPart.cs 2007-04-30 08:59:18 UTC (rev 187)
@@ -0,0 +1,88 @@
+/*
+ * Copyright 2004-2006 Luke Quinane and Daniel Frampton
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+using System;
+
+namespace NMail.DataTypes.Message {
+ /// <summary>
+ /// Represents a block of message data.
+ /// </summary>
+ [Serializable]
+ public class MessageDataPart : IMessagePart {
+ /// <summary>
+ /// The data for this class.
+ /// </summary>
+ protected ByteString data;
+
+ /// <summary>
+ /// Creates a message data part from the given lines.
+ /// </summary>
+ /// <param name="data">The lines to create the data from.</param>
+ public MessageDataPart(ByteString data) {
+ this.data = data;
+
+ if (this.data == null) {
+ this.data = ByteString.Empty;
+ }
+ }
+
+ /// <summary>
+ /// Appends a line onto the end of the data.
+ /// </summary>
+ /// <param name="line">The line to append</param>
+ public void Append(string line) {
+ AppendEnd(line);
+ }
+
+ /// <summary>
+ /// Appends a line onto the start of the data.
+ /// </summary>
+ /// <param name="line">The line to append</param>
+ public void AppendStart(string line) {
+ this.data = this.data.Prepend(line);
+ }
+
+ /// <summary>
+ /// Appends a line onto the end of the data.
+ /// </summary>
+ /// <param name="line">The line to append</param>
+ public void AppendEnd(string line) {
+ this.data = this.data.Postfix(line);
+ }
+
+ /// <summary>
+ /// The size of the data in bytes.
+ /// </summary>
+ public virtual int Size {
+ get {
+ return this.data.Length;
+ }
+ }
+
+ /// <summary>
+ /// The data as a single string.
+ /// </summary>
+ public virtual ByteString Data {
+ get {
+ return this.data;
+ }
+ set {
+ this.data = value;
+ }
+ }
+ }
+}
Added: NMail/trunk/NMail/DataTypes/Message/MessageHeaders.cs
===================================================================
--- NMail/trunk/NMail/DataTypes/Message/MessageHeaders.cs (rev 0)
+++ NMail/trunk/NMail/DataTypes/Message/MessageHeaders.cs 2007-04-30 08:59:18 UTC (rev 187)
@@ -0,0 +1,232 @@
+/*
+ * Copyright 2004-2006 Luke Quinane and Daniel Frampton
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+using System;
+using System.Collections;
+using System.Collections.Specialized;
+using System.Text;
+using System.Text.RegularExpressions;
+
+using NMail.Helper;
+
+namespace NMail.DataTypes.Message {
+ /// <summary>
+ /// A set of message headers for an email message.
+ /// </summary>
+ [Serializable]
+ public class MessageHeaders : IMessagePart {
+ /// <summary>
+ /// The raw headers for this set of message headers
+ /// </summary>
+ private ByteString rawHeaders;
+
+ /// <summary>
+ /// A hashtable of arraylists for each header
+ /// </summary>
+ private Hashtable parsedHeaders;
+
+ /// <summary>
+ /// Are the current set of message headers parsed.
+ /// </summary>
+ private bool parsed;
+
+ /// <summary>
+ /// Creates a new set of message headers from the set of lines.
+ /// </summary>
+ public MessageHeaders() : this(ByteString.Empty) {}
+
+ /// <summary>
+ /// Creates a new set of message headers from the set of lines.
+ /// </summary>
+ /// <param name="data">The lines to create the headers from.</param>
+ public MessageHeaders(ByteString data) {
+ this.Data = data;
+ }
+
+ /// <summary>
+ /// Gets the value of the first header associated with the given name.
+ /// </summary>
+ /// <param name="name">The name of the header to lookup, e.g "Subject".</param>
+ /// <returns>The returned header, e.g. "A subject".</returns>
+ public string GetSingleHeader(string name) {
+ if (!this.parsed) parseRawHeaders();
+
+ ArrayList headerList = (ArrayList) this.parsedHeaders[name];
+ return (headerList == null) ?
+ null :
+ (string) headerList[0];
+ }
+
+ /// <summary>
+ /// Gets the value for all headers associated with the given name.
+ /// </summary>
+ /// <param name="name">The name of the headers to lookup, e.g "Received".</param>
+ /// <returns>An array of corresponding headers.</returns>
+ public string[] GetHeaders(string name) {
+ if (!this.parsed) parseRawHeaders();
+
+ ArrayList headerList = (ArrayList) this.parsedHeaders[name];
+ return (headerList == null) ?
+ null :
+ (string[]) headerList.ToArray(typeof(string));
+ }
+
+ /// <summary>
+ /// Appends a header line onto the end of the message headers.
+ /// </summary>
+ /// <param name="headerLine">The valid complete line of header information.</param>
+ public void AppendEnd(string headerLine) {
+ // Parse the new header line
+ int indexOfColon = headerLine.IndexOf(':');
+ if (indexOfColon <= 0) {
+ throw new ArgumentException("Only valid headers can be appended.");
+ }
+ string headerName = headerLine.Substring(0, indexOfColon).T...
[truncated message content] |