/// <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); }
/// <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);
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; } }
/// <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);
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; }
/// <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));
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; }
/// <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); }
/// <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); }
internal static void Encode (StringBuilder builder, BodyPart body) { if (body == null) { builder.Append ("NIL"); return; } builder.Append ('('); body.Encode (builder); builder.Append (')'); }
/// <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));
/// <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));
/// <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));
/// <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); }
/// <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; }
/// <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); }
public MessageSelectedEventArgs (IMailFolder folder, UniqueId uid, BodyPart body) { Folder = folder; UniqueId = uid; Body = body; }
/// <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); }
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; }
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); }
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); } }