An abstract body part of a message.
Each body part will actually be a BodyPartBasic, BodyPartText, BodyPartMessage, or BodyPartMultipart.
Пример #1
0
		/// <summary>
		/// Asynchronously get the specified body part.
		/// </summary>
		/// <remarks>
		/// Asynchronously gets the specified body part.
		/// </remarks>
		/// <returns>The body part.</returns>
		/// <param name="uid">The UID of the message.</param>
		/// <param name="part">The body part.</param>
		/// <param name="cancellationToken">The cancellation token.</param>
		/// <param name="progress">The progress reporting mechanism.</param>
		/// <exception cref="System.ArgumentNullException">
		/// <paramref name="part"/> is <c>null</c>.
		/// </exception>
		/// <exception cref="System.ArgumentException">
		/// <paramref name="uid"/> is invalid.
		/// </exception>
		/// <exception cref="System.ObjectDisposedException">
		/// The <see cref="IMailStore"/> has been disposed.
		/// </exception>
		/// <exception cref="ServiceNotConnectedException">
		/// The <see cref="IMailStore"/> is not connected.
		/// </exception>
		/// <exception cref="ServiceNotAuthenticatedException">
		/// The <see cref="IMailStore"/> is not authenticated.
		/// </exception>
		/// <exception cref="FolderNotOpenException">
		/// The folder is not currently open.
		/// </exception>
		/// <exception cref="MessageNotFoundException">
		/// The <see cref="IMailStore"/> did not return the requested message body.
		/// </exception>
		/// <exception cref="System.OperationCanceledException">
		/// The operation was canceled via the cancellation token.
		/// </exception>
		/// <exception cref="System.IO.IOException">
		/// An I/O error occurred.
		/// </exception>
		/// <exception cref="ProtocolException">
		/// The server's response contained unexpected tokens.
		/// </exception>
		/// <exception cref="CommandException">
		/// The command failed.
		/// </exception>
		public virtual Task<MimeEntity> GetBodyPartAsync (UniqueId uid, BodyPart part, CancellationToken cancellationToken = default (CancellationToken), ITransferProgress progress = null)
		{
			if (part == null)
				throw new ArgumentNullException ("part");

			return Task.Factory.StartNew (() => {
				lock (SyncRoot) {
					return GetBodyPart (uid, part, cancellationToken, progress);
				}
			}, cancellationToken, TaskCreationOptions.None, TaskScheduler.Default);
		}
Пример #2
0
		/// <summary>
		/// Get the specified body part.
		/// </summary>
		/// <remarks>
		/// Gets the specified body part.
		/// </remarks>
		/// <returns>The body part.</returns>
		/// <param name="index">The index of the message.</param>
		/// <param name="part">The body part.</param>
		/// <param name="headersOnly"><c>true</c> if only the headers should be downloaded; otherwise, <c>false</c>></param>
		/// <param name="cancellationToken">The cancellation token.</param>
		/// <param name="progress">The progress reporting mechanism.</param>
		/// <exception cref="System.ArgumentNullException">
		/// <paramref name="part"/> is <c>null</c>.
		/// </exception>
		/// <exception cref="System.ArgumentOutOfRangeException">
		/// <paramref name="index"/> is out of range.
		/// </exception>
		/// <exception cref="System.ObjectDisposedException">
		/// The <see cref="IMailStore"/> has been disposed.
		/// </exception>
		/// <exception cref="ServiceNotConnectedException">
		/// The <see cref="IMailStore"/> is not connected.
		/// </exception>
		/// <exception cref="ServiceNotAuthenticatedException">
		/// The <see cref="IMailStore"/> is not authenticated.
		/// </exception>
		/// <exception cref="FolderNotOpenException">
		/// The folder is not currently open.
		/// </exception>
		/// <exception cref="MessageNotFoundException">
		/// The <see cref="IMailStore"/> did not return the requested message body.
		/// </exception>
		/// <exception cref="System.OperationCanceledException">
		/// The operation was canceled via the cancellation token.
		/// </exception>
		/// <exception cref="System.IO.IOException">
		/// An I/O error occurred.
		/// </exception>
		/// <exception cref="ProtocolException">
		/// The server's response contained unexpected tokens.
		/// </exception>
		/// <exception cref="CommandException">
		/// The command failed.
		/// </exception>
		public abstract MimeEntity GetBodyPart (int index, BodyPart part, bool headersOnly, CancellationToken cancellationToken = default (CancellationToken), ITransferProgress progress = null);
Пример #3
0
		static void VerifyPartSpecifier (BodyPart part)
		{
			var expected = part.ContentType.Parameters["part-specifier"];

			Assert.AreEqual (expected, part.PartSpecifier, "The part-specifier does not match for {0}", part.ContentType.MimeType);

			var message = part as BodyPartMessage;
			if (message != null) {
				VerifyPartSpecifier (message.Body);
				return;
			}

			var multipart = part as BodyPartMultipart;
			if (multipart != null) {
				for (int i = 0; i < multipart.BodyParts.Count; i++)
					VerifyPartSpecifier (multipart.BodyParts[i]);
				return;
			}
		}
Пример #4
0
		/// <summary>
		/// Get the specified body part.
		/// </summary>
		/// <remarks>
		/// Gets the specified body part.
		/// </remarks>
		/// <returns>The body part.</returns>
		/// <param name="uid">The UID of the message.</param>
		/// <param name="part">The body part.</param>
		/// <param name="cancellationToken">The cancellation token.</param>
		/// <param name="progress">The progress reporting mechanism.</param>
		/// <exception cref="System.ArgumentNullException">
		/// <paramref name="part"/> is <c>null</c>.
		/// </exception>
		/// <exception cref="System.ArgumentException">
		/// <paramref name="uid"/> is invalid.
		/// </exception>
		/// <exception cref="System.ObjectDisposedException">
		/// The <see cref="IMailStore"/> has been disposed.
		/// </exception>
		/// <exception cref="ServiceNotConnectedException">
		/// The <see cref="IMailStore"/> is not connected.
		/// </exception>
		/// <exception cref="ServiceNotAuthenticatedException">
		/// The <see cref="IMailStore"/> is not authenticated.
		/// </exception>
		/// <exception cref="FolderNotOpenException">
		/// The folder is not currently open.
		/// </exception>
		/// <exception cref="MessageNotFoundException">
		/// The <see cref="IMailStore"/> did not return the requested message body.
		/// </exception>
		/// <exception cref="System.OperationCanceledException">
		/// The operation was canceled via the cancellation token.
		/// </exception>
		/// <exception cref="System.IO.IOException">
		/// An I/O error occurred.
		/// </exception>
		/// <exception cref="ProtocolException">
		/// The server's response contained unexpected tokens.
		/// </exception>
		/// <exception cref="CommandException">
		/// The command failed.
		/// </exception>
		public abstract MimeEntity GetBodyPart (UniqueId uid, BodyPart part, CancellationToken cancellationToken = default (CancellationToken), ITransferProgress progress = null);
Пример #5
0
		static IEnumerable<BodyPartBasic> EnumerateBodyParts (BodyPart entity)
		{
			if (entity == null)
				yield break;

			var multipart = entity as BodyPartMultipart;

			if (multipart != null) {
				foreach (var subpart in multipart.BodyParts) {
					foreach (var part in EnumerateBodyParts (subpart))
						yield return part;
				}

				yield break;
			}

			var msgpart = entity as BodyPartMessage;

			if (msgpart != null) {
				var message = msgpart.Body;

				if (message != null) {
					foreach (var part in EnumerateBodyParts (message))
						yield return part;
				}

				yield break;
			}

			yield return (BodyPartBasic) entity;
		}
Пример #6
0
 /// <summary>
 /// Get the specified body part.
 /// </summary>
 /// <remarks>
 /// Gets the specified body part.
 /// </remarks>
 /// <returns>The body part.</returns>
 /// <param name="uid">The UID of the message.</param>
 /// <param name="part">The body part.</param>
 /// <param name="cancellationToken">The cancellation token.</param>
 /// <exception cref="System.ArgumentNullException">
 /// <paramref name="part"/> is <c>null</c>.
 /// </exception>
 /// <exception cref="System.ArgumentException">
 /// <paramref name="uid"/> is invalid.
 /// </exception>
 /// <exception cref="System.ObjectDisposedException">
 /// The <see cref="IMailStore"/> has been disposed.
 /// </exception>
 /// <exception cref="System.InvalidOperationException">
 /// <para>The <see cref="IMailStore"/> is not connected.</para>
 /// <para>-or-</para>
 /// <para>The <see cref="IMailStore"/> is not authenticated.</para>
 /// <para>-or-</para>
 /// <para>The folder is not currently open.</para>
 /// </exception>
 /// <exception cref="System.OperationCanceledException">
 /// The operation was canceled via the cancellation token.
 /// </exception>
 /// <exception cref="System.IO.IOException">
 /// An I/O error occurred.
 /// </exception>
 /// <exception cref="ProtocolException">
 /// The server's response contained unexpected tokens.
 /// </exception>
 /// <exception cref="CommandException">
 /// The command failed.
 /// </exception>
 public abstract MimeEntity GetBodyPart(UniqueId uid, BodyPart part, CancellationToken cancellationToken = default (CancellationToken));
Пример #7
0
		static bool TryParse (string text, ref int index, string path, out BodyPart part)
		{
			ContentDisposition disposition;
			ContentType contentType;
			string[] array;
			string nstring;
			Uri location;
			uint number;

			part = null;

			while (index < text.Length && text[index] == ' ')
				index++;

			if (index >= text.Length || text[index] != '(') {
				if (index + 3 <= text.Length && text.Substring (index, 3) == "NIL") {
					index += 3;
					return true;
				}

				return false;
			}

			index++;

			if (index >= text.Length)
				return false;

			if (text[index] == '(') {
				var prefix = path.Length > 0 ? path + "." : string.Empty;
				var multipart = new BodyPartMultipart ();
				IList<BodyPart> children;

				if (!TryParse (text, ref index, prefix, out children))
					return false;

				foreach (var child in children)
					multipart.BodyParts.Add (child);

				if (!TryParse (text, ref index, true, out contentType))
					return false;

				multipart.ContentType = contentType;

				if (!TryParse (text, ref index, out disposition))
					return false;

				multipart.ContentDisposition = disposition;

				if (!TryParse (text, ref index, out array))
					return false;

				multipart.ContentLanguage = array;

				if (!TryParse (text, ref index, out location))
					return false;

				multipart.ContentLocation = location;

				part = multipart;
			} else {
				BodyPartMessage message = null;
				BodyPartText txt = null;
				BodyPartBasic basic;

				if (!TryParse (text, ref index, false, out contentType))
					return false;

				if (contentType.Matches ("message", "rfc822"))
					basic = message = new BodyPartMessage ();
				else if (contentType.Matches ("text", "*"))
					basic = txt = new BodyPartText ();
				else
					basic = new BodyPartBasic ();

				basic.ContentType = contentType;

				if (!TryParse (text, ref index, out nstring))
					return false;

				basic.ContentId = nstring;

				if (!TryParse (text, ref index, out nstring))
					return false;

				basic.ContentDescription = nstring;

				if (!TryParse (text, ref index, out nstring))
					return false;

				basic.ContentTransferEncoding = nstring;

				if (!TryParse (text, ref index, out number))
					return false;

				basic.Octets = number;

				if (!TryParse (text, ref index, out nstring))
					return false;

				basic.ContentMd5 = nstring;

				if (!TryParse (text, ref index, out disposition))
					return false;

				basic.ContentDisposition = disposition;

				if (!TryParse (text, ref index, out array))
					return false;

				basic.ContentLanguage = array;

				if (!TryParse (text, ref index, out location))
					return false;

				basic.ContentLocation = location;

				if (message != null) {
					Envelope envelope;
					BodyPart body;

					if (!Envelope.TryParse (text, ref index, out envelope))
						return false;

					message.Envelope = envelope;

					if (!TryParse (text, ref index, path, out body))
						return false;

					message.Body = body;

					if (!TryParse (text, ref index, out number))
						return false;

					message.Lines = number;
				} else if (txt != null) {
					if (!TryParse (text, ref index, out number))
						return false;

					txt.Lines = number;
				}

				part = basic;
			}

			part.PartSpecifier = path;

			if (index >= text.Length || text[index] != ')')
				return false;

			index++;

			return true;
		}
Пример #8
0
		/// <summary>
		/// Get a substream of the specified body part.
		/// </summary>
		/// <remarks>
		/// Gets a substream of the body part. If the starting offset is beyond
		/// the end of the body part, an empty stream is returned. If the number of
		/// bytes desired extends beyond the end of the body part, a truncated stream
		/// will be returned.
		/// </remarks>
		/// <returns>The stream.</returns>
		/// <param name="index">The index of the message.</param>
		/// <param name="part">The desired body part.</param>
		/// <param name="offset">The starting offset of the first desired byte.</param>
		/// <param name="count">The number of bytes desired.</param>
		/// <param name="cancellationToken">The cancellation token.</param>
		/// <param name="progress">The progress reporting mechanism.</param>
		/// <exception cref="System.ArgumentNullException">
		/// <paramref name="part"/> is <c>null</c>.
		/// </exception>
		/// <exception cref="System.ArgumentOutOfRangeException">
		/// <para><paramref name="index"/> is out of range.</para>
		/// <para>-or-</para>
		/// <para><paramref name="offset"/> is negative.</para>
		/// <para>-or-</para>
		/// <para><paramref name="count"/> is negative.</para>
		/// </exception>
		/// <exception cref="System.ObjectDisposedException">
		/// The <see cref="IMailStore"/> has been disposed.
		/// </exception>
		/// <exception cref="ServiceNotConnectedException">
		/// The <see cref="IMailStore"/> is not connected.
		/// </exception>
		/// <exception cref="ServiceNotAuthenticatedException">
		/// The <see cref="IMailStore"/> is not authenticated.
		/// </exception>
		/// <exception cref="FolderNotOpenException">
		/// The folder is not currently open.
		/// </exception>
		/// <exception cref="MessageNotFoundException">
		/// The <see cref="IMailStore"/> did not return the requested message stream.
		/// </exception>
		/// <exception cref="System.OperationCanceledException">
		/// The operation was canceled via the cancellation token.
		/// </exception>
		/// <exception cref="System.IO.IOException">
		/// An I/O error occurred.
		/// </exception>
		/// <exception cref="ProtocolException">
		/// The server's response contained unexpected tokens.
		/// </exception>
		/// <exception cref="CommandException">
		/// The command failed.
		/// </exception>
		public virtual Stream GetStream (int index, BodyPart part, int offset, int count, CancellationToken cancellationToken = default (CancellationToken), ITransferProgress progress = null)
		{
			if (index < 0 || index >= Count)
				throw new ArgumentOutOfRangeException ("index");

			if (part == null)
				throw new ArgumentNullException ("part");

			if (offset < 0)
				throw new ArgumentOutOfRangeException ("offset");

			if (count < 0)
				throw new ArgumentOutOfRangeException ("count");

			return GetStream (index, part.PartSpecifier, offset, count, cancellationToken, progress);
		}
Пример #9
0
        /// <summary>
        /// Asynchronously get a substream of the specified body part.
        /// </summary>
        /// <remarks>
        /// Asynchronously gets a substream of the body part. If the starting offset is beyond
        /// the end of the body part, an empty stream is returned. If the number of
        /// bytes desired extends beyond the end of the body part, a truncated stream
        /// will be returned.
        /// </remarks>
        /// <returns>The stream.</returns>
        /// <param name="uid">The UID of the message.</param>
        /// <param name="part">The desired body part.</param>
        /// <param name="offset">The starting offset of the first desired byte.</param>
        /// <param name="count">The number of bytes desired.</param>
        /// <param name="cancellationToken">The cancellation token.</param>
        /// <exception cref="System.ArgumentException">
        /// <paramref name="uid"/> is invalid.
        /// </exception>
        /// <exception cref="System.ArgumentNullException">
        /// <paramref name="part"/> is <c>null</c>.
        /// </exception>
        /// <exception cref="System.ArgumentOutOfRangeException">
        /// <para><paramref name="offset"/> is negative.</para>
        /// <para>-or-</para>
        /// <para><paramref name="count"/> is negative.</para>
        /// </exception>
        /// <exception cref="System.ObjectDisposedException">
        /// The <see cref="IMailStore"/> has been disposed.
        /// </exception>
        /// <exception cref="System.InvalidOperationException">
        /// <para>The <see cref="IMailStore"/> is not connected.</para>
        /// <para>-or-</para>
        /// <para>The <see cref="IMailStore"/> is not authenticated.</para>
        /// <para>-or-</para>
        /// <para>The folder is not currently open.</para>
        /// </exception>
        /// <exception cref="System.OperationCanceledException">
        /// The operation was canceled via the cancellation token.
        /// </exception>
        /// <exception cref="System.IO.IOException">
        /// An I/O error occurred.
        /// </exception>
        /// <exception cref="ProtocolException">
        /// The server's response contained unexpected tokens.
        /// </exception>
        /// <exception cref="CommandException">
        /// The command failed.
        /// </exception>
        public virtual Task<Stream> GetStreamAsync(UniqueId uid, BodyPart part, int offset, int count, CancellationToken cancellationToken = default (CancellationToken))
        {
            if (part == null)
                throw new ArgumentNullException ("part");

            if (offset < 0)
                throw new ArgumentOutOfRangeException ("offset");

            if (count < 0)
                throw new ArgumentOutOfRangeException ("count");

            return Task.Factory.StartNew (() => {
                lock (SyncRoot) {
                    return GetStream (uid, part, offset, count, cancellationToken);
                }
            }, cancellationToken, TaskCreationOptions.None, TaskScheduler.Default);
        }
Пример #10
0
		internal static void Encode (StringBuilder builder, BodyPart body)
		{
			if (body == null) {
				builder.Append ("NIL");
				return;
			}

			builder.Append ('(');
			body.Encode (builder);
			builder.Append (')');
		}
Пример #11
0
 /// <summary>
 /// Get a substream of the specified body part.
 /// </summary>
 /// <remarks>
 /// Gets a substream of the body part. If the starting offset is beyond
 /// the end of the body part, an empty stream is returned. If the number of
 /// bytes desired extends beyond the end of the body part, a truncated stream
 /// will be returned.
 /// </remarks>
 /// <returns>The stream.</returns>
 /// <param name="index">The index of the message.</param>
 /// <param name="part">The desired body part.</param>
 /// <param name="offset">The starting offset of the first desired byte.</param>
 /// <param name="count">The number of bytes desired.</param>
 /// <param name="cancellationToken">The cancellation token.</param>
 /// <exception cref="System.ArgumentNullException">
 /// <paramref name="part"/> is <c>null</c>.
 /// </exception>
 /// <exception cref="System.ArgumentOutOfRangeException">
 /// <para><paramref name="index"/> is out of range.</para>
 /// <para>-or-</para>
 /// <para><paramref name="offset"/> is negative.</para>
 /// <para>-or-</para>
 /// <para><paramref name="count"/> is negative.</para>
 /// </exception>
 /// <exception cref="System.ObjectDisposedException">
 /// The <see cref="IMailStore"/> has been disposed.
 /// </exception>
 /// <exception cref="System.InvalidOperationException">
 /// <para>The <see cref="IMailStore"/> is not connected.</para>
 /// <para>-or-</para>
 /// <para>The <see cref="IMailStore"/> is not authenticated.</para>
 /// <para>-or-</para>
 /// <para>The folder is not currently open.</para>
 /// </exception>
 /// <exception cref="System.OperationCanceledException">
 /// The operation was canceled via the cancellation token.
 /// </exception>
 /// <exception cref="System.IO.IOException">
 /// An I/O error occurred.
 /// </exception>
 /// <exception cref="ProtocolException">
 /// The server's response contained unexpected tokens.
 /// </exception>
 /// <exception cref="CommandException">
 /// The command failed.
 /// </exception>
 public abstract Stream GetStream(int index, BodyPart part, int offset, int count, CancellationToken cancellationToken = default (CancellationToken));
Пример #12
0
 /// <summary>
 /// Get a substream of the specified body part.
 /// </summary>
 /// <remarks>
 /// Gets a substream of the body part. If the starting offset is beyond
 /// the end of the body part, an empty stream is returned. If the number of
 /// bytes desired extends beyond the end of the body part, a truncated stream
 /// will be returned.
 /// </remarks>
 /// <returns>The stream.</returns>
 /// <param name="uid">The UID of the message.</param>
 /// <param name="part">The desired body part.</param>
 /// <param name="offset">The starting offset of the first desired byte.</param>
 /// <param name="count">The number of bytes desired.</param>
 /// <param name="cancellationToken">The cancellation token.</param>
 /// <exception cref="System.ArgumentException">
 /// <paramref name="uid"/> is invalid.
 /// </exception>
 /// <exception cref="System.ArgumentNullException">
 /// <paramref name="part"/> is <c>null</c>.
 /// </exception>
 /// <exception cref="System.ArgumentOutOfRangeException">
 /// <para><paramref name="offset"/> is negative.</para>
 /// <para>-or-</para>
 /// <para><paramref name="count"/> is negative.</para>
 /// </exception>
 /// <exception cref="System.ObjectDisposedException">
 /// The <see cref="IMailStore"/> has been disposed.
 /// </exception>
 /// <exception cref="System.InvalidOperationException">
 /// <para>The <see cref="IMailStore"/> is not connected.</para>
 /// <para>-or-</para>
 /// <para>The <see cref="IMailStore"/> is not authenticated.</para>
 /// <para>-or-</para>
 /// <para>The folder is not currently open.</para>
 /// </exception>
 /// <exception cref="System.OperationCanceledException">
 /// The operation was canceled via the cancellation token.
 /// </exception>
 /// <exception cref="System.IO.IOException">
 /// An I/O error occurred.
 /// </exception>
 /// <exception cref="ProtocolException">
 /// The server's response contained unexpected tokens.
 /// </exception>
 /// <exception cref="CommandException">
 /// The command failed.
 /// </exception>
 public abstract Stream GetStream(UniqueId uid, BodyPart part, int offset, int count, CancellationToken cancellationToken = default (CancellationToken));
Пример #13
0
 /// <summary>
 /// Get the specified body part.
 /// </summary>
 /// <remarks>
 /// Gets the specified body part.
 /// </remarks>
 /// <returns>The body part.</returns>
 /// <param name="index">The index of the message.</param>
 /// <param name="part">The body part.</param>
 /// <param name="headersOnly"><c>true</c> if only the headers should be downloaded; otherwise, <c>false</c>></param>
 /// <param name="cancellationToken">The cancellation token.</param>
 /// <exception cref="System.ArgumentNullException">
 /// <paramref name="part"/> is <c>null</c>.
 /// </exception>
 /// <exception cref="System.ArgumentOutOfRangeException">
 /// <paramref name="index"/> is out of range.
 /// </exception>
 /// <exception cref="System.ObjectDisposedException">
 /// The <see cref="IMailStore"/> has been disposed.
 /// </exception>
 /// <exception cref="System.InvalidOperationException">
 /// <para>The <see cref="IMailStore"/> is not connected.</para>
 /// <para>-or-</para>
 /// <para>The <see cref="IMailStore"/> is not authenticated.</para>
 /// <para>-or-</para>
 /// <para>The folder is not currently open.</para>
 /// </exception>
 /// <exception cref="System.OperationCanceledException">
 /// The operation was canceled via the cancellation token.
 /// </exception>
 /// <exception cref="System.IO.IOException">
 /// An I/O error occurred.
 /// </exception>
 /// <exception cref="ProtocolException">
 /// The server's response contained unexpected tokens.
 /// </exception>
 /// <exception cref="CommandException">
 /// The command failed.
 /// </exception>
 public abstract MimeEntity GetBodyPart(int index, BodyPart part, bool headersOnly, CancellationToken cancellationToken = default (CancellationToken));
Пример #14
0
		/// <summary>
		/// Asynchronously get the specified body part.
		/// </summary>
		/// <remarks>
		/// Asynchronously gets the specified body part.
		/// </remarks>
		/// <returns>The body part.</returns>
		/// <param name="index">The index of the message.</param>
		/// <param name="part">The body part.</param>
		/// <param name="headersOnly"><c>true</c> if only the headers should be downloaded; otherwise, <c>false</c>></param>
		/// <param name="cancellationToken">The cancellation token.</param>
		/// <param name="progress">The progress reporting mechanism.</param>
		/// <exception cref="System.ArgumentNullException">
		/// <paramref name="part"/> is <c>null</c>.
		/// </exception>
		/// <exception cref="System.ArgumentOutOfRangeException">
		/// <paramref name="index"/> is out of range.
		/// </exception>
		/// <exception cref="System.ObjectDisposedException">
		/// The <see cref="IMailStore"/> has been disposed.
		/// </exception>
		/// <exception cref="ServiceNotConnectedException">
		/// The <see cref="IMailStore"/> is not connected.
		/// </exception>
		/// <exception cref="ServiceNotAuthenticatedException">
		/// The <see cref="IMailStore"/> is not authenticated.
		/// </exception>
		/// <exception cref="FolderNotOpenException">
		/// The folder is not currently open.
		/// </exception>
		/// <exception cref="MessageNotFoundException">
		/// The <see cref="IMailStore"/> did not return the requested message body.
		/// </exception>
		/// <exception cref="System.OperationCanceledException">
		/// The operation was canceled via the cancellation token.
		/// </exception>
		/// <exception cref="System.IO.IOException">
		/// An I/O error occurred.
		/// </exception>
		/// <exception cref="ProtocolException">
		/// The server's response contained unexpected tokens.
		/// </exception>
		/// <exception cref="CommandException">
		/// The command failed.
		/// </exception>
		public virtual Task<MimeEntity> GetBodyPartAsync (int index, BodyPart part, bool headersOnly, CancellationToken cancellationToken = default (CancellationToken), ITransferProgress progress = null)
		{
			if (index < 0 || index >= Count)
				throw new ArgumentOutOfRangeException ("index");

			if (part == null)
				throw new ArgumentNullException ("part");

			return Task.Factory.StartNew (() => {
				lock (SyncRoot) {
					return GetBodyPart (index, part, headersOnly, cancellationToken, progress);
				}
			}, cancellationToken, TaskCreationOptions.None, TaskScheduler.Default);
		}
Пример #15
0
		/// <summary>
		/// Tries to parse the given text into a new <see cref="MailKit.BodyPart"/> instance.
		/// </summary>
		/// <remarks>
		/// <para>Parses a body part from the specified text.</para>
		/// <para>Note: This syntax, while similar to IMAP's BODYSTRUCTURE syntax, is not completely compatible.</para>
		/// </remarks>
		/// <returns><c>true</c>, if the body part was successfully parsed, <c>false</c> otherwise.</returns>
		/// <param name="text">The text to parse.</param>
		/// <param name="part">The parsed body part.</param>
		/// <exception cref="System.ArgumentNullException">
		/// <paramref name="text"/> is <c>null</c>.
		/// </exception>
		public static bool TryParse (string text, out BodyPart part)
		{
			if (text == null)
				throw new ArgumentNullException ("text");

			int index = 0;

			return TryParse (text, ref index, string.Empty, out part) && index == text.Length;
		}
Пример #16
0
		/// <summary>
		/// Get a substream of the specified body part.
		/// </summary>
		/// <remarks>
		/// Gets a substream of the body part. If the starting offset is beyond
		/// the end of the body part, an empty stream is returned. If the number of
		/// bytes desired extends beyond the end of the body part, a truncated stream
		/// will be returned.
		/// </remarks>
		/// <returns>The stream.</returns>
		/// <param name="uid">The UID of the message.</param>
		/// <param name="part">The desired body part.</param>
		/// <param name="offset">The starting offset of the first desired byte.</param>
		/// <param name="count">The number of bytes desired.</param>
		/// <param name="cancellationToken">The cancellation token.</param>
		/// <param name="progress">The progress reporting mechanism.</param>
		/// <exception cref="System.ArgumentException">
		/// <paramref name="uid"/> is invalid.
		/// </exception>
		/// <exception cref="System.ArgumentNullException">
		/// <paramref name="part"/> is <c>null</c>.
		/// </exception>
		/// <exception cref="System.ArgumentOutOfRangeException">
		/// <para><paramref name="offset"/> is negative.</para>
		/// <para>-or-</para>
		/// <para><paramref name="count"/> is negative.</para>
		/// </exception>
		/// <exception cref="System.ObjectDisposedException">
		/// The <see cref="IMailStore"/> has been disposed.
		/// </exception>
		/// <exception cref="ServiceNotConnectedException">
		/// The <see cref="IMailStore"/> is not connected.
		/// </exception>
		/// <exception cref="ServiceNotAuthenticatedException">
		/// The <see cref="IMailStore"/> is not authenticated.
		/// </exception>
		/// <exception cref="FolderNotOpenException">
		/// The folder is not currently open.
		/// </exception>
		/// <exception cref="MessageNotFoundException">
		/// The <see cref="IMailStore"/> did not return the requested message stream.
		/// </exception>
		/// <exception cref="System.OperationCanceledException">
		/// The operation was canceled via the cancellation token.
		/// </exception>
		/// <exception cref="System.IO.IOException">
		/// An I/O error occurred.
		/// </exception>
		/// <exception cref="ProtocolException">
		/// The server's response contained unexpected tokens.
		/// </exception>
		/// <exception cref="CommandException">
		/// The command failed.
		/// </exception>
		public virtual Stream GetStream (UniqueId uid, BodyPart part, int offset, int count, CancellationToken cancellationToken = default (CancellationToken), ITransferProgress progress = null)
		{
			if (uid.Id == 0)
				throw new ArgumentException ("The uid is invalid.", "uid");

			if (part == null)
				throw new ArgumentNullException ("part");

			if (offset < 0)
				throw new ArgumentOutOfRangeException ("offset");

			if (count < 0)
				throw new ArgumentOutOfRangeException ("count");

			return GetStream (uid, part.PartSpecifier, offset, count, cancellationToken, progress);
		}
Пример #17
0
		public MessageSelectedEventArgs (IMailFolder folder, UniqueId uid, BodyPart body)
		{
			Folder = folder;
			UniqueId = uid;
			Body = body;
		}
Пример #18
0
		/// <summary>
		/// Asynchronously get a substream of the specified body part.
		/// </summary>
		/// <remarks>
		/// Asynchronously gets a substream of the body part. If the starting offset is beyond
		/// the end of the body part, an empty stream is returned. If the number of
		/// bytes desired extends beyond the end of the body part, a truncated stream
		/// will be returned.
		/// </remarks>
		/// <returns>The stream.</returns>
		/// <param name="index">The index of the message.</param>
		/// <param name="part">The desired body part.</param>
		/// <param name="offset">The starting offset of the first desired byte.</param>
		/// <param name="count">The number of bytes desired.</param>
		/// <param name="cancellationToken">The cancellation token.</param>
		/// <param name="progress">The progress reporting mechanism.</param>
		/// <exception cref="System.ArgumentNullException">
		/// <paramref name="part"/> is <c>null</c>.
		/// </exception>
		/// <exception cref="System.ArgumentOutOfRangeException">
		/// <para><paramref name="index"/> is out of range.</para>
		/// <para>-or-</para>
		/// <para><paramref name="offset"/> is negative.</para>
		/// <para>-or-</para>
		/// <para><paramref name="count"/> is negative.</para>
		/// </exception>
		/// <exception cref="System.ObjectDisposedException">
		/// The <see cref="IMailStore"/> has been disposed.
		/// </exception>
		/// <exception cref="ServiceNotConnectedException">
		/// The <see cref="IMailStore"/> is not connected.
		/// </exception>
		/// <exception cref="ServiceNotAuthenticatedException">
		/// The <see cref="IMailStore"/> is not authenticated.
		/// </exception>
		/// <exception cref="FolderNotOpenException">
		/// The folder is not currently open.
		/// </exception>
		/// <exception cref="MessageNotFoundException">
		/// The <see cref="IMailStore"/> did not return the requested message stream.
		/// </exception>
		/// <exception cref="System.OperationCanceledException">
		/// The operation was canceled via the cancellation token.
		/// </exception>
		/// <exception cref="System.IO.IOException">
		/// An I/O error occurred.
		/// </exception>
		/// <exception cref="ProtocolException">
		/// The server's response contained unexpected tokens.
		/// </exception>
		/// <exception cref="CommandException">
		/// The command failed.
		/// </exception>
		public virtual Task<Stream> GetStreamAsync (int index, BodyPart part, int offset, int count, CancellationToken cancellationToken = default (CancellationToken), ITransferProgress progress = null)
		{
			if (index < 0 || index >= Count)
				throw new ArgumentOutOfRangeException ("index");

			if (part == null)
				throw new ArgumentNullException ("part");

			if (offset < 0)
				throw new ArgumentOutOfRangeException ("offset");

			if (count < 0)
				throw new ArgumentOutOfRangeException ("count");

			return Task.Factory.StartNew (() => {
				lock (SyncRoot) {
					return GetStream (index, part, offset, count, cancellationToken, progress);
				}
			}, cancellationToken, TaskCreationOptions.None, TaskScheduler.Default);
		}
Пример #19
0
		static BodyPartMessage CreateMessage (string type, string subtype, string partSpecifier, BodyPart body)
		{
			var message = new BodyPartMessage { ContentType = CreateContentType (type, subtype, partSpecifier) };
			message.Body = body;
			return message;
		}
Пример #20
0
        static bool TryParse(string text, ref int index, string path, out BodyPart part)
        {
            ContentDisposition disposition;
            ContentType        contentType;

            string[] array;
            string   nstring;
            Uri      location;
            uint     number;

            part = null;

            while (index < text.Length && text[index] == ' ')
            {
                index++;
            }

            if (index >= text.Length || text[index] != '(')
            {
                if (index + 3 <= text.Length && text.Substring(index, 3) == "NIL")
                {
                    index += 3;
                    return(true);
                }

                return(false);
            }

            index++;

            if (index >= text.Length)
            {
                return(false);
            }

            if (text[index] == '(')
            {
                var prefix    = path.Length > 0 ? path + "." : string.Empty;
                var multipart = new BodyPartMultipart();
                IList <BodyPart> children;

                if (!TryParse(text, ref index, prefix, out children))
                {
                    return(false);
                }

                foreach (var child in children)
                {
                    multipart.BodyParts.Add(child);
                }

                if (!TryParse(text, ref index, true, out contentType))
                {
                    return(false);
                }

                multipart.ContentType = contentType;

                if (!TryParse(text, ref index, out disposition))
                {
                    return(false);
                }

                multipart.ContentDisposition = disposition;

                if (!TryParse(text, ref index, out array))
                {
                    return(false);
                }

                multipart.ContentLanguage = array;

                if (!TryParse(text, ref index, out location))
                {
                    return(false);
                }

                multipart.ContentLocation = location;

                part = multipart;
            }
            else
            {
                BodyPartMessage message = null;
                BodyPartText    txt     = null;
                BodyPartBasic   basic;

                if (!TryParse(text, ref index, false, out contentType))
                {
                    return(false);
                }

                if (contentType.IsMimeType("message", "rfc822"))
                {
                    basic = message = new BodyPartMessage();
                }
                else if (contentType.IsMimeType("text", "*"))
                {
                    basic = txt = new BodyPartText();
                }
                else
                {
                    basic = new BodyPartBasic();
                }

                basic.ContentType = contentType;

                if (!TryParse(text, ref index, out nstring))
                {
                    return(false);
                }

                basic.ContentId = nstring;

                if (!TryParse(text, ref index, out nstring))
                {
                    return(false);
                }

                basic.ContentDescription = nstring;

                if (!TryParse(text, ref index, out nstring))
                {
                    return(false);
                }

                basic.ContentTransferEncoding = nstring;

                if (!TryParse(text, ref index, out number))
                {
                    return(false);
                }

                basic.Octets = number;

                if (!TryParse(text, ref index, out nstring))
                {
                    return(false);
                }

                basic.ContentMd5 = nstring;

                if (!TryParse(text, ref index, out disposition))
                {
                    return(false);
                }

                basic.ContentDisposition = disposition;

                if (!TryParse(text, ref index, out array))
                {
                    return(false);
                }

                basic.ContentLanguage = array;

                if (!TryParse(text, ref index, out location))
                {
                    return(false);
                }

                basic.ContentLocation = location;

                if (message != null)
                {
                    Envelope envelope;
                    BodyPart body;

                    if (!Envelope.TryParse(text, ref index, out envelope))
                    {
                        return(false);
                    }

                    message.Envelope = envelope;

                    if (!TryParse(text, ref index, path, out body))
                    {
                        return(false);
                    }

                    message.Body = body;

                    if (!TryParse(text, ref index, out number))
                    {
                        return(false);
                    }

                    message.Lines = number;
                }
                else if (txt != null)
                {
                    if (!TryParse(text, ref index, out number))
                    {
                        return(false);
                    }

                    txt.Lines = number;
                }

                part = basic;
            }

            part.PartSpecifier = path;

            if (index >= text.Length || text[index] != ')')
            {
                return(false);
            }

            index++;

            return(true);
        }
Пример #21
0
		void Render (IMailFolder folder, UniqueId uid, BodyPart body)
		{
			var multipart = body as BodyPartMultipart;

			if (multipart != null && body.ContentType.Matches ("multipart", "related")) {
				RenderRelated (folder, uid, multipart);
				return;
			}

			var text = body as BodyPartText;

			if (multipart != null) {
				if (multipart.ContentType.Matches ("multipart", "alternative")) {
					// A multipart/alternative is just a collection of alternate views.
					// The last part is the format that most closely matches what the
					// user saw in his or her email client's WYSIWYG editor.
					for (int i = multipart.BodyParts.Count; i > 0; i--) {
						var multi = multipart.BodyParts[i - 1] as BodyPartMultipart;

						if (multi != null && multi.ContentType.Matches ("multipart", "related")) {
							if (multi.BodyParts.Count == 0)
								continue;

							var start = multi.ContentType.Parameters["start"];
							var root = multi.BodyParts[0];

							if (!string.IsNullOrEmpty (start)) {
								// if the 'start' parameter is set, it overrides the default behavior of using the first
								// body part as the main document.
								root = multi.BodyParts.OfType<BodyPartText> ().FirstOrDefault (x => x.ContentId == start);
							}

							if (root != null && root.ContentType.Matches ("text", "html")) {
								Render (folder, uid, multi);
								return;
							}

							continue;
						}

						text = multipart.BodyParts[i - 1] as BodyPartText;

						if (text != null) {
							RenderText (folder, uid, text);
							return;
						}
					}
				} else if (multipart.BodyParts.Count > 0) {
					// The main message body is usually the first part of a multipart/mixed.
					Render (folder, uid, multipart.BodyParts[0]);
				}
			} else if (text != null) {
				RenderText (folder, uid, text);
			}
		}