MailKit.Net.Imap.ImapCommand.Step C# (CSharp) Method

Step() public method

Sends the next part of the command to the server.
/// The operation was canceled via the cancellation token. /// /// An I/O error occurred. /// /// An IMAP protocol error occurred. ///
public Step ( ) : bool
return bool
		public bool Step ()
		{
			var supportsLiteralPlus = (Engine.Capabilities & ImapCapabilities.LiteralPlus) != 0;
			int timeout = Engine.Stream.CanTimeout ? Engine.Stream.ReadTimeout : -1;
			var idle = UserData as ImapIdleContext;
			var result = ImapCommandResponse.None;
			ImapToken token;

			// construct and write the command tag if this is the initial state
			if (current == 0) {
				Tag = string.Format ("{0}{1:D8}", Engine.TagPrefix, Engine.Tag++);

				var buf = Encoding.ASCII.GetBytes (Tag + " ");
				Engine.Stream.Write (buf, 0, buf.Length, CancellationToken);
			}

			do {
				var command = parts[current].Command;

				Engine.Stream.Write (command, 0, command.Length, CancellationToken);

				// if the server doesn't support LITERAL+ (or LITERAL-), we'll need to wait
				// for a "+" response before writing out the any literals...
				if (parts[current].WaitForContinuation)
					break;

				// otherwise, we can write out any and all literal tokens we have...
				parts[current].Literal.WriteTo (Engine.Stream, CancellationToken);

				if (current + 1 >= parts.Count)
					break;

				current++;
			} while (true);

			Engine.Stream.Flush (CancellationToken);

			// now we need to read the response...
			do {
				if (Engine.State == ImapEngineState.Idle) {
					try {
						if (Engine.Stream.CanTimeout)
							Engine.Stream.ReadTimeout = -1;

						token = Engine.ReadToken (idle.LinkedToken);

						if (Engine.Stream.CanTimeout)
							Engine.Stream.ReadTimeout = timeout;
					} catch (OperationCanceledException) {
						if (Engine.Stream.CanTimeout)
							Engine.Stream.ReadTimeout = timeout;

						if (idle.IsCancellationRequested)
							throw;

						Engine.Stream.IsConnected = true;

						token = Engine.ReadToken (CancellationToken);
					}
				} else {
					token = Engine.ReadToken (CancellationToken);
				}

				if (token.Type == ImapTokenType.Atom && token.Value.ToString () == "+") {
					// we've gotten a continuation response from the server
					var text = Engine.ReadLine (CancellationToken).Trim ();

					// if we've got a Literal pending, the '+' means we can send it now...
					if (!supportsLiteralPlus && parts[current].Literal != null) {
						parts[current].Literal.WriteTo (Engine.Stream, CancellationToken);
						break;
					}

					Debug.Assert (ContinuationHandler != null, "The ImapCommand's ContinuationHandler is null");

					ContinuationHandler (Engine, this, text);
				} else if (token.Type == ImapTokenType.Asterisk) {
					// we got an untagged response, let the engine handle this...
					Engine.ProcessUntaggedResponse (CancellationToken);
				} else if (token.Type == ImapTokenType.Atom && (string) token.Value == Tag) {
					// the next token should be "OK", "NO", or "BAD"
					token = Engine.ReadToken (CancellationToken);

					if (token.Type == ImapTokenType.Atom) {
						string atom = (string) token.Value;

						switch (atom) {
						case "BAD": result = ImapCommandResponse.Bad; break;
						case "OK": result = ImapCommandResponse.Ok; break;
						case "NO": result = ImapCommandResponse.No; break;
						default: throw ImapEngine.UnexpectedToken ("Syntax error in tagged response. Unexpected token: {0}", token);
						}

						token = Engine.ReadToken (CancellationToken);
						if (token.Type == ImapTokenType.OpenBracket) {
							var code = Engine.ParseResponseCode (CancellationToken);
							RespCodes.Add (code);
							break;
						}

						if (token.Type != ImapTokenType.Eoln) {
							// consume the rest of the line...
							ResponseText = ((string) (token.Value) + Engine.ReadLine (CancellationToken)).TrimEnd ();
							break;
						}
					} else {
						// looks like we didn't get an "OK", "NO", or "BAD"...
						throw ImapEngine.UnexpectedToken ("Syntax error in tagged response. Unexpected token: {0}", token);
					}
				} else if (token.Type == ImapTokenType.OpenBracket) {
					// Note: this is a work-around for broken IMAP servers like Office365.com that
					// return RESP-CODES that are not preceded by "* OK " such as the example in
					// issue #115 (https://github.com/jstedfast/MailKit/issues/115).
					var code = Engine.ParseResponseCode (CancellationToken);
					RespCodes.Add (code);
				} else {
					// no clue what we got...
					throw ImapEngine.UnexpectedToken ("Syntax error in response. Unexpected token: {0}", token);
				}
			} while (true);

			// the status should always be Active at this point, but just to be sure...
			if (Status == ImapCommandStatus.Active) {
				current++;

				if (current >= parts.Count || result != ImapCommandResponse.None) {
					Status = ImapCommandStatus.Complete;
					Response = result;
					return false;
				}
			}

			return true;
		}
	}

Usage Example

Esempio n. 1
0
        /// <summary>
        /// Iterate the command pipeline.
        /// </summary>
        public int Iterate()
        {
            if (stream == null)
                throw new InvalidOperationException ();

            if (queue.Count == 0)
                return 0;

            current = queue[0];
            queue.RemoveAt (0);

            try {
                current.CancellationToken.ThrowIfCancellationRequested ();
            } catch (OperationCanceledException) {
                // FIXME: is this right??
                queue.RemoveAll (x => x.CancellationToken == current.CancellationToken);
                throw;
            }

            current.Status = ImapCommandStatus.Active;

            try {
                while (current.Step ()) {
                    // more literal data to send...
                }

                if (current.Bye)
                    Disconnect ();
            } catch {
                Disconnect ();
                throw;
            }

            return current.Id;
        }
All Usage Examples Of MailKit.Net.Imap.ImapCommand::Step