public static Task WriteStatusAsync(this ImapStream stream, string status, string message) { return(stream.WriteLineAsync(status + " " + message)); }
/// <summary> /// https://tools.ietf.org/html/rfc3501#section-2.2.1 /// https://tools.ietf.org/html/rfc3501#section-4.3 /// </summary> public static async Task <CommandLine> ReadCommandAsync(this ImapStream stream) { var line = await stream.ReadLineAsync(); while (String.IsNullOrEmpty(line)) { await stream.WriteLineAsync("* BAD Empty command line"); line = await stream.ReadLineAsync(); } var spl = line.Split(new char[] { ' ' }, 3); // No command name if (spl.Length < 2) { return(null); } var result = new CommandLine { Tag = spl[0], Name = spl[1].ToUpperInvariant() }; // No argument if (spl.Length < 3) { return(result); } // Rest part as default argument result.Args = spl[2]; // APPEND is special to handle later if (result.Name == "APPEND") { return(result); } var partialArgs = ArgumentUtility.Parse(result.Args); // One line command if (partialArgs.Size == null) { return(result); } /* Continous command * R <tag> <command> <partial argument>{<continue size>} * W + Continue. * R ... * R <partial argument>{<continue size>} * W + Continue. * R ... * R <end argument> */ var builder = new StringBuilder(); while (partialArgs.Size != null) { builder.Append(partialArgs.Args); await stream.WriteLineAsync("+ Continue."); // Read bytes secified by literal {size} var bytes = await stream.ReadAsync(partialArgs.Size.Value); builder.Append(TextUtils.QuoteString(Encoding.UTF8.GetString(bytes))); // Try to read last line line = await stream.ReadLineAsync(); partialArgs = ArgumentUtility.Parse(line); } builder.Append(partialArgs.Args); result.Args = builder.ToString(); return(result); }