An IMAP literal object.
Ejemplo n.º 1
0
		public ImapCommandPart (byte[] command, ImapLiteral literal)
		{
			Command = command;
			Literal = literal;
		}
Ejemplo n.º 2
0
		/// <summary>
		/// Initializes a new instance of the <see cref="MailKit.Net.Imap.ImapCommand"/> class.
		/// </summary>
		/// <remarks>
		/// Creates a new <see cref="MailKit.Net.Imap.ImapCommand"/>.
		/// </remarks>
		/// <param name="engine">The IMAP engine that will be sending the command.</param>
		/// <param name="cancellationToken">The cancellation token.</param>
		/// <param name="folder">The IMAP folder that the command operates on.</param>
		/// <param name="options">The formatting options.</param>
		/// <param name="format">The command format.</param>
		/// <param name="args">The command arguments.</param>
		public ImapCommand (ImapEngine engine, CancellationToken cancellationToken, ImapFolder folder, FormatOptions options, string format, params object[] args)
		{
			UntaggedHandlers = new Dictionary<string, ImapUntaggedHandler> ();
			RespCodes = new List<ImapResponseCode> ();
			CancellationToken = cancellationToken;
			Response = ImapCommandResponse.None;
			Status = ImapCommandStatus.Created;
			Engine = engine;
			Folder = folder;

			using (var builder = new MemoryStream ()) {
				var plus = (Engine.Capabilities & ImapCapabilities.LiteralPlus) != 0 ? "+" : string.Empty;
				int argc = 0;
				byte[] buf;
				string str;
				char c;

				for (int i = 0; i < format.Length; i++) {
					if (format[i] == '%') {
						switch (format[++i]) {
						case '%': // a literal %
							builder.WriteByte ((byte) '%');
							break;
						case 'c': // a character
							c = (char) args[argc++];
							builder.WriteByte ((byte) c);
							break;
						case 'd': // an integer
							str = ((int) args[argc++]).ToString ();
							buf = Encoding.ASCII.GetBytes (str);
							builder.Write (buf, 0, buf.Length);
							break;
						case 'u': // an unsigned integer
							str = ((uint) args[argc++]).ToString ();
							buf = Encoding.ASCII.GetBytes (str);
							builder.Write (buf, 0, buf.Length);
							break;
						case 'F': // an ImapFolder
							var utf7 = ((ImapFolder) args[argc++]).EncodedName;
							AppendString (options, true, builder, utf7);
							break;
						case 'L':
							var literal = new ImapLiteral (options, args[argc++], UpdateProgress);
							var length = literal.Length;

							totalSize += length;

							if (options.International)
								str = "UTF8 (~{" + length + plus + "}\r\n";
							else
								str = "{" + length + plus + "}\r\n";

							buf = Encoding.ASCII.GetBytes (str);
							builder.Write (buf, 0, buf.Length);

							parts.Add (new ImapCommandPart (builder.ToArray (), literal));
							builder.SetLength (0);

							if (options.International)
								builder.WriteByte ((byte) ')');
							break;
						case 'S': // a string which may need to be quoted or made into a literal
							AppendString (options, true, builder, (string) args[argc++]);
							break;
						case 'Q': // similar to %S but string must be quoted at a minimum
							AppendString (options, false, builder, (string) args[argc++]);
							break;
						case 's': // a safe atom string
							buf = Encoding.ASCII.GetBytes ((string) args[argc++]);
							builder.Write (buf, 0, buf.Length);
							break;
						default:
							throw new FormatException ();
						}
					} else {
						builder.WriteByte ((byte) format[i]);
					}
				}

				parts.Add (new ImapCommandPart (builder.ToArray (), null));
			}
		}
Ejemplo n.º 3
0
        /// <summary>
        /// Initializes a new instance of the <see cref="MailKit.Net.Imap.ImapCommand"/> class.
        /// </summary>
        /// <remarks>
        /// Creates a new <see cref="MailKit.Net.Imap.ImapCommand"/>.
        /// </remarks>
        /// <param name="engine">The IMAP engine that will be sending the command.</param>
        /// <param name="cancellationToken">The cancellation token.</param>
        /// <param name="folder">The IMAP folder that the command operates on.</param>
        /// <param name="options">The formatting options.</param>
        /// <param name="format">The command format.</param>
        /// <param name="args">The command arguments.</param>
        public ImapCommand(ImapEngine engine, CancellationToken cancellationToken, ImapFolder folder, FormatOptions options, string format, params object[] args)
        {
            UntaggedHandlers  = new Dictionary <string, ImapUntaggedHandler> ();
            Logout            = format.Equals("LOGOUT\r\n", StringComparison.Ordinal);
            RespCodes         = new List <ImapResponseCode> ();
            CancellationToken = cancellationToken;
            Response          = ImapCommandResponse.None;
            Status            = ImapCommandStatus.Created;
            Engine            = engine;
            Folder            = folder;

            using (var builder = new MemoryStream()) {
                int    argc = 0;
                byte[] buf;
                string str;

                for (int i = 0; i < format.Length; i++)
                {
                    if (format[i] == '%')
                    {
                        switch (format[++i])
                        {
                        case '%':                         // a literal %
                            builder.WriteByte((byte)'%');
                            break;

                        case 'd':                         // an integer
                            str = ((int)args[argc++]).ToString(CultureInfo.InvariantCulture);
                            buf = Encoding.ASCII.GetBytes(str);
                            builder.Write(buf, 0, buf.Length);
                            break;

                        case 'u':                         // an unsigned integer
                            str = ((uint)args[argc++]).ToString(CultureInfo.InvariantCulture);
                            buf = Encoding.ASCII.GetBytes(str);
                            builder.Write(buf, 0, buf.Length);
                            break;

                        case 's':
                            str = (string)args[argc++];
                            buf = Encoding.ASCII.GetBytes(str);
                            builder.Write(buf, 0, buf.Length);
                            break;

                        case 'F':                         // an ImapFolder
                            var utf7 = ((ImapFolder)args[argc++]).EncodedName;
                            AppendString(options, true, builder, utf7);
                            break;

                        case 'L':                         // a MimeMessage
                            var  literal = new ImapLiteral(options, (MimeMessage)args[argc++], UpdateProgress);
                            var  prefix  = options.International ? UTF8LiteralTokenPrefix : LiteralTokenPrefix;
                            var  length  = literal.Length;
                            bool wait    = true;

                            builder.Write(prefix, 0, prefix.Length);
                            buf = Encoding.ASCII.GetBytes(length.ToString(CultureInfo.InvariantCulture));
                            builder.Write(buf, 0, buf.Length);

                            if (CanUseNonSynchronizedLiteral(Engine, length))
                            {
                                builder.WriteByte((byte)'+');
                                wait = false;
                            }

                            builder.Write(LiteralTokenSuffix, 0, LiteralTokenSuffix.Length);

                            totalSize += length;

                            parts.Add(new ImapCommandPart(builder.ToArray(), literal, wait));
                            builder.SetLength(0);

                            if (options.International)
                            {
                                builder.WriteByte((byte)')');
                            }
                            break;

                        case 'S':                         // a string which may need to be quoted or made into a literal
                            AppendString(options, true, builder, (string)args[argc++]);
                            break;

                        case 'Q':                         // similar to %S but string must be quoted at a minimum
                            AppendString(options, false, builder, (string)args[argc++]);
                            break;

                        default:
                            throw new FormatException();
                        }
                    }
                    else
                    {
                        builder.WriteByte((byte)format[i]);
                    }
                }

                parts.Add(new ImapCommandPart(builder.ToArray(), null));
            }
        }
Ejemplo n.º 4
0
        internal static int EstimateCommandLength(ImapEngine engine, FormatOptions options, string format, params object[] args)
        {
            const int EstimatedTagLength = 10;
            var       eoln   = false;
            int       length = 0;
            int       argc   = 0;
            string    str;

            for (int i = 0; i < format.Length; i++)
            {
                if (format[i] == '%')
                {
                    switch (format[++i])
                    {
                    case '%':                     // a literal %
                        length++;
                        break;

                    case 'd':                     // an integer
                        str     = ((int)args[argc++]).ToString(CultureInfo.InvariantCulture);
                        length += str.Length;
                        break;

                    case 'u':                     // an unsigned integer
                        str     = ((uint)args[argc++]).ToString(CultureInfo.InvariantCulture);
                        length += str.Length;
                        break;

                    case 's':
                        str     = (string)args[argc++];
                        length += str.Length;
                        break;

                    case 'F':                     // an ImapFolder
                        var utf7 = ((ImapFolder)args[argc++]).EncodedName;
                        length += EstimateStringLength(engine, options, true, utf7, out eoln);
                        break;

                    case 'L':                     // a MimeMessage
                        var literal = new ImapLiteral(options, (MimeMessage)args[argc++], null);
                        var prefix  = options.International ? UTF8LiteralTokenPrefix : LiteralTokenPrefix;
                        var len     = literal.Length;

                        length += prefix.Length;
                        length += Encoding.ASCII.GetByteCount(len.ToString(CultureInfo.InvariantCulture));

                        if (CanUseNonSynchronizedLiteral(engine, len))
                        {
                            length++;
                        }

                        length += LiteralTokenSuffix.Length;

                        if (options.International)
                        {
                            length++;
                        }

                        eoln = true;
                        break;

                    case 'S':                     // a string which may need to be quoted or made into a literal
                        length += EstimateStringLength(engine, options, true, (string)args[argc++], out eoln);
                        break;

                    case 'Q':                     // similar to %S but string must be quoted at a minimum
                        length += EstimateStringLength(engine, options, false, (string)args[argc++], out eoln);
                        break;

                    default:
                        throw new FormatException();
                    }

                    if (eoln)
                    {
                        break;
                    }
                }
                else
                {
                    length++;
                }
            }

            return(length + EstimatedTagLength);
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Initializes a new instance of the <see cref="MailKit.Net.Imap.ImapCommand"/> class.
        /// </summary>
        /// <remarks>
        /// Creates a new <see cref="MailKit.Net.Imap.ImapCommand"/>.
        /// </remarks>
        /// <param name="engine">The IMAP engine that will be sending the command.</param>
        /// <param name="cancellationToken">The cancellation token.</param>
        /// <param name="folder">The IMAP folder that the command operates on.</param>
        /// <param name="options">The formatting options.</param>
        /// <param name="format">The command format.</param>
        /// <param name="args">The command arguments.</param>
        public ImapCommand(ImapEngine engine, CancellationToken cancellationToken, ImapFolder folder, FormatOptions options, string format, params object[] args)
        {
            UntaggedHandlers  = new Dictionary <string, ImapUntaggedHandler> ();
            RespCodes         = new List <ImapResponseCode> ();
            CancellationToken = cancellationToken;
            Status            = ImapCommandStatus.Created;
            Result            = ImapCommandResult.None;
            Engine            = engine;
            Folder            = folder;

            using (var builder = new MemoryStream()) {
                var    plus = (Engine.Capabilities & ImapCapabilities.LiteralPlus) != 0 ? "+" : string.Empty;
                int    argc = 0;
                byte[] buf;
                string str;
                char   c;

                for (int i = 0; i < format.Length; i++)
                {
                    if (format[i] == '%')
                    {
                        switch (format[++i])
                        {
                        case '%':                         // a literal %
                            builder.WriteByte((byte)'%');
                            break;

                        case 'c':                         // a character
                            c = (char)args[argc++];
                            builder.WriteByte((byte)c);
                            break;

                        case 'd':                         // an integer
                            str = ((int)args[argc++]).ToString();
                            buf = Encoding.ASCII.GetBytes(str);
                            builder.Write(buf, 0, buf.Length);
                            break;

                        case 'u':                         // an unsigned integer
                            str = ((uint)args[argc++]).ToString();
                            buf = Encoding.ASCII.GetBytes(str);
                            builder.Write(buf, 0, buf.Length);
                            break;

                        case 'F':                         // an ImapFolder
                            var utf7 = ((ImapFolder)args[argc++]).EncodedName;
                            AppendString(options, true, builder, utf7);
                            break;

                        case 'L':
                            var literal = new ImapLiteral(options, args[argc++]);
                            var length  = literal.Length;

                            if (options.International)
                            {
                                str = "UTF8 (~{" + length + plus + "}\r\n";
                            }
                            else
                            {
                                str = "{" + length + plus + "}\r\n";
                            }

                            buf = Encoding.ASCII.GetBytes(str);
                            builder.Write(buf, 0, buf.Length);

                            parts.Add(new ImapCommandPart(builder.ToArray(), literal));
                            builder.SetLength(0);

                            if (options.International)
                            {
                                builder.WriteByte((byte)')');
                            }
                            break;

                        case 'S':                         // a string which may need to be quoted or made into a literal
                            AppendString(options, true, builder, (string)args[argc++]);
                            break;

                        case 'Q':                         // similar to %S but string must be quoted at a minimum
                            AppendString(options, false, builder, (string)args[argc++]);
                            break;

                        case 's':                         // a safe atom string
                            buf = Encoding.ASCII.GetBytes((string)args[argc++]);
                            builder.Write(buf, 0, buf.Length);
                            break;

                        default:
                            throw new FormatException();
                        }
                    }
                    else
                    {
                        builder.WriteByte((byte)format[i]);
                    }
                }

                parts.Add(new ImapCommandPart(builder.ToArray(), null));
            }
        }
Ejemplo n.º 6
0
 public ImapCommandPart(byte[] command, ImapLiteral literal, bool wait = true)
 {
     WaitForContinuation = wait;
     Command             = command;
     Literal             = literal;
 }
Ejemplo n.º 7
0
 public ImapCommandPart(byte[] command, ImapLiteral literal)
 {
     Command = command;
     Literal = literal;
 }
Ejemplo n.º 8
0
		/// <summary>
		/// Initializes a new instance of the <see cref="MailKit.Net.Imap.ImapCommand"/> class.
		/// </summary>
		/// <param name="engine">The IMAP engine that will be sending the command.</param>
		/// <param name="cancellationToken">The cancellation token.</param>
		/// <param name="folder">The IMAP folder that the command operates on.</param>
		/// <param name="format">The command format.</param>
		/// <param name="args">The command arguments.</param>
		public ImapCommand (ImapEngine engine, CancellationToken cancellationToken, ImapFolder folder, string format, params object[] args)
		{
			UntaggedHandlers = new Dictionary<string, ImapUntaggedHandler> ();
			RespCodes = new List<ImapResponseCode> ();
			CancellationToken = cancellationToken;
			Status = ImapCommandStatus.Created;
			Result = ImapCommandResult.None;
			Engine = engine;
			Folder = folder;

			using (var builder = new MemoryStream ()) {
				int argc = 0;
				byte[] buf;
				string str;
				char c;

				for (int i = 0; i < format.Length; i++) {
					if (format[i] == '%') {
						switch (format[++i]) {
						case '%': // a literal %
							builder.WriteByte ((byte) '%');
							break;
						case 'c': // a character
							c = (char) args[argc++];
							builder.WriteByte ((byte) c);
							break;
						case 'd': // an integer
							str = ((int) args[argc++]).ToString ();
							buf = Encoding.ASCII.GetBytes (str);
							builder.Write (buf, 0, buf.Length);
							break;
						case 'u': // an unsigned integer
							str = ((uint) args[argc++]).ToString ();
							buf = Encoding.ASCII.GetBytes (str);
							builder.Write (buf, 0, buf.Length);
							break;
						case 'F': // an ImapFolder
							var utf7 = ((ImapFolder) args[argc++]).EncodedName;
							AppendString (builder, utf7);
							break;
						case 'L':
							var literal = new ImapLiteral (args[argc++]);
							var length = literal.Length;

							buf = Encoding.ASCII.GetBytes (length.ToString ());

							// FIXME: support LITERAL+?
							builder.WriteByte ((byte) '{');
							builder.Write (buf, 0, buf.Length);
							builder.WriteByte ((byte) '}');
							builder.WriteByte ((byte) '\r');
							builder.WriteByte ((byte) '\n');

							parts.Add (new ImapCommandPart (builder.ToArray (), literal));
							builder.SetLength (0);
							break;
						case 'S': // a string which may need to be quoted or made into a literal
							AppendString (builder, (string) args[argc++]);
							break;
						case 's': // a safe atom string
							buf = Encoding.ASCII.GetBytes ((string) args[argc++]);
							builder.Write (buf, 0, buf.Length);
							break;
						default:
							throw new FormatException ();
						}
					} else {
						builder.WriteByte ((byte) format[i]);
					}
				}

				parts.Add (new ImapCommandPart (builder.ToArray (), null));
			}
		}
Ejemplo n.º 9
0
        /// <summary>
        /// Initializes a new instance of the <see cref="MailKit.Net.Imap.ImapCommand"/> class.
        /// </summary>
        /// <remarks>
        /// Creates a new <see cref="MailKit.Net.Imap.ImapCommand"/>.
        /// </remarks>
        /// <param name="engine">The IMAP engine that will be sending the command.</param>
        /// <param name="cancellationToken">The cancellation token.</param>
        /// <param name="folder">The IMAP folder that the command operates on.</param>
        /// <param name="options">The formatting options.</param>
        /// <param name="format">The command format.</param>
        /// <param name="args">The command arguments.</param>
        public ImapCommand(ImapEngine engine, CancellationToken cancellationToken, ImapFolder folder, FormatOptions options, string format, params object[] args)
        {
            UntaggedHandlers  = new Dictionary <string, ImapUntaggedHandler> (StringComparer.OrdinalIgnoreCase);
            Logout            = format.Equals("LOGOUT\r\n", StringComparison.Ordinal);
            RespCodes         = new List <ImapResponseCode> ();
            CancellationToken = cancellationToken;
            Response          = ImapCommandResponse.None;
            Status            = ImapCommandStatus.Created;
            Engine            = engine;
            Folder            = folder;

            using (var builder = new ByteArrayBuilder(1024)) {
                byte[] buf, utf8 = new byte[8];
                int    argc      = 0;
                string str;

                for (int i = 0; i < format.Length; i++)
                {
                    if (format[i] == '%')
                    {
                        switch (format[++i])
                        {
                        case '%':                         // a literal %
                            builder.Append((byte)'%');
                            break;

                        case 'd':                         // an integer
                            str = ((int)args[argc++]).ToString(CultureInfo.InvariantCulture);
                            buf = Encoding.ASCII.GetBytes(str);
                            builder.Append(buf, 0, buf.Length);
                            break;

                        case 'u':                         // an unsigned integer
                            str = ((uint)args[argc++]).ToString(CultureInfo.InvariantCulture);
                            buf = Encoding.ASCII.GetBytes(str);
                            builder.Append(buf, 0, buf.Length);
                            break;

                        case 's':
                            str = (string)args[argc++];
                            buf = Encoding.ASCII.GetBytes(str);
                            builder.Append(buf, 0, buf.Length);
                            break;

                        case 'F':                         // an ImapFolder
                            var utf7 = ((ImapFolder)args[argc++]).EncodedName;
                            AppendString(options, true, builder, utf7);
                            break;

                        case 'L':                         // a MimeMessage or a byte[]
                            var         arg = args[argc++];
                            ImapLiteral literal;
                            byte[]      prefix;

                            if (arg is MimeMessage message)
                            {
                                prefix  = options.International ? UTF8LiteralTokenPrefix : LiteralTokenPrefix;
                                literal = new ImapLiteral(options, message, UpdateProgress);
                            }
                            else
                            {
                                literal = new ImapLiteral(options, (byte[])arg);
                                prefix  = LiteralTokenPrefix;
                            }

                            var  length = literal.Length;
                            bool wait   = true;

                            builder.Append(prefix, 0, prefix.Length);
                            buf = Encoding.ASCII.GetBytes(length.ToString(CultureInfo.InvariantCulture));
                            builder.Append(buf, 0, buf.Length);

                            if (CanUseNonSynchronizedLiteral(Engine, length))
                            {
                                builder.Append((byte)'+');
                                wait = false;
                            }

                            builder.Append(LiteralTokenSuffix, 0, LiteralTokenSuffix.Length);

                            totalSize += length;

                            parts.Add(new ImapCommandPart(builder.ToArray(), literal, wait));
                            builder.Clear();

                            if (prefix == UTF8LiteralTokenPrefix)
                            {
                                builder.Append((byte)')');
                            }
                            break;

                        case 'S':                         // a string which may need to be quoted or made into a literal
                            AppendString(options, true, builder, (string)args[argc++]);
                            break;

                        case 'Q':                         // similar to %S but string must be quoted at a minimum
                            AppendString(options, false, builder, (string)args[argc++]);
                            break;

                        default:
                            throw new FormatException();
                        }
                    }
                    else if (format[i] < 128)
                    {
                        builder.Append((byte)format[i]);
                    }
                    else
                    {
                        int nchars = char.IsSurrogate(format[i]) ? 2 : 1;
                        int nbytes = Encoding.UTF8.GetBytes(format, i, nchars, utf8, 0);
                        builder.Append(utf8, 0, nbytes);
                        i += nchars - 1;
                    }
                }

                parts.Add(new ImapCommandPart(builder.ToArray(), null));
            }
        }
Ejemplo n.º 10
0
		public ImapCommandPart (byte[] command, ImapLiteral literal, bool wait = true)
		{
			WaitForContinuation = wait;
			Command = command;
			Literal = literal;
		}
Ejemplo n.º 11
0
        /// <summary>
        /// Initializes a new instance of the <see cref="MailKit.Net.Imap.ImapCommand"/> class.
        /// </summary>
        /// <param name="engine">The IMAP engine that will be sending the command.</param>
        /// <param name="cancellationToken">The cancellation token.</param>
        /// <param name="folder">The IMAP folder that the command operates on.</param>
        /// <param name="format">The command format.</param>
        /// <param name="args">The command arguments.</param>
        public ImapCommand(ImapEngine engine, CancellationToken cancellationToken, ImapFolder folder, string format, params object[] args)
        {
            UntaggedHandlers  = new Dictionary <string, ImapUntaggedHandler> ();
            RespCodes         = new List <ImapResponseCode> ();
            CancellationToken = cancellationToken;
            Status            = ImapCommandStatus.Created;
            Result            = ImapCommandResult.None;
            Engine            = engine;
            Folder            = folder;

            using (var builder = new MemoryStream()) {
                int    argc = 0;
                byte[] buf;
                string str;
                char   c;

                for (int i = 0; i < format.Length; i++)
                {
                    if (format[i] == '%')
                    {
                        switch (format[++i])
                        {
                        case '%':                         // a literal %
                            builder.WriteByte((byte)'%');
                            break;

                        case 'c':                         // a character
                            c = (char)args[argc++];
                            builder.WriteByte((byte)c);
                            break;

                        case 'd':                         // an integer
                            str = ((int)args[argc++]).ToString();
                            buf = Encoding.ASCII.GetBytes(str);
                            builder.Write(buf, 0, buf.Length);
                            break;

                        case 'u':                         // an unsigned integer
                            str = ((uint)args[argc++]).ToString();
                            buf = Encoding.ASCII.GetBytes(str);
                            builder.Write(buf, 0, buf.Length);
                            break;

                        case 'F':                         // an ImapFolder
                            var utf7 = ((ImapFolder)args[argc++]).EncodedName;
                            AppendString(builder, utf7);
                            break;

                        case 'L':
                            var literal = new ImapLiteral(args[argc++]);
                            var length  = literal.Length;

                            buf = Encoding.ASCII.GetBytes(length.ToString());

                            // FIXME: support LITERAL+?
                            builder.WriteByte((byte)'{');
                            builder.Write(buf, 0, buf.Length);
                            builder.WriteByte((byte)'}');
                            builder.WriteByte((byte)'\r');
                            builder.WriteByte((byte)'\n');

                            parts.Add(new ImapCommandPart(builder.ToArray(), literal));
                            builder.SetLength(0);
                            break;

                        case 'S':                         // a string which may need to be quoted or made into a literal
                            AppendString(builder, (string)args[argc++]);
                            break;

                        case 's':                         // a safe atom string
                            buf = Encoding.ASCII.GetBytes((string)args[argc++]);
                            builder.Write(buf, 0, buf.Length);
                            break;

                        default:
                            throw new FormatException();
                        }
                    }
                    else
                    {
                        builder.WriteByte((byte)format[i]);
                    }
                }

                parts.Add(new ImapCommandPart(builder.ToArray(), null));
            }
        }