// Fetches message headers and returns them as a list of Message objects. public List <Message> FetchHeaders(int startSeqNum, int count, bool useUid) { var messages = new List <Message>(count); if (startSeqNum < 1 || count < 1) { return(messages); } string tag = NextTag(); string command; if (useUid) { command = "{0} UID FETCH {1}:{2} (FLAGS BODY[HEADER.FIELDS (SUBJECT DATE FROM TO)] UID)"; } else { command = "{0} FETCH {1}:{2} (FLAGS BODY[HEADER.FIELDS (SUBJECT DATE FROM TO)] UID)"; } SendString(string.Format(command, tag, startSeqNum, startSeqNum + count - 1)); int bytesInBuffer = 0; bool doneFetching = false; while (!doneFetching) { // Read the next chunk from the stream. int bytesRead = this.sslStream.Read(this.buffer, bytesInBuffer, this.buffer.Length - bytesInBuffer); string strBuffer = Encoding.ASCII.GetString(this.buffer, 0, bytesInBuffer + bytesRead); Match match; string remainder = strBuffer; bool doneMatching = false; while (!doneMatching) { // Each untagged response item represents one message. string unTaggedResponsePattern = "(^|\r\n)(\\* (.*\r\n)*?)(\\*|" + tag + ") "; match = Regex.Match(remainder, unTaggedResponsePattern); if (match.Success) { string untaggedResponse = match.Groups[2].ToString(); Message message = ImapParser.ParseFetchHeader(untaggedResponse); if (message != null) { messages.Add(message); } remainder = remainder.Substring(match.Groups[2].ToString().Length); } else { // Did not find an untagged response. Check if it is a tagged response. string taggedResponsePattern = "^" + tag + " .*\r\n"; match = Regex.Match(remainder, taggedResponsePattern); if (match.Success) { doneMatching = true; doneFetching = true; } else { // Neither untagged nor tagged response was found. Maybe only a portion of // the response was read. Move the dangling bytes to the front of the buffer // for the next read. doneMatching = true; if (remainder.Length > 0) { for (int i = 0; i < remainder.Length; ++i) { this.buffer[i] = (byte)remainder[i]; } bytesInBuffer = remainder.Length; } } } } } return(messages); }
// Fetches message headers and returns them as a list of Message objects. // SelectMailbox must be called to select the mailbox before calling this method. public List <Message> FetchHeaders(int startSeqNum, int count, bool useUid) { if (string.IsNullOrEmpty(SelectedMailboxName)) { Error = "Mailbox must be selected before FETCH operation. (Account: " + Account.AccountName + ")"; Debug.WriteLine("ImapClient.FetchHeaders(): Mailbox is not selected. (Account: " + Account.AccountName + ")"); return(null); } if (startSeqNum < 1 || count < 1) { return(null); } var messages = new List <Message>(count); string tag = NextTag(); string command = useUid ? "{0} UID FETCH {1}:{2} (UID FLAGS BODY[HEADER.FIELDS (SUBJECT DATE FROM TO)] BODYSTRUCTURE)" : "{0} FETCH {1}:{2} (UID FLAGS BODY[HEADER.FIELDS (SUBJECT DATE FROM TO)] BODYSTRUCTURE)"; if (!SendString(string.Format(command, tag, startSeqNum, startSeqNum + count - 1))) { return(null); } int bytesInBuffer = 0; bool doneFetching = false; while (!doneFetching) { int bytesRead; // Read the next chunk from the stream. try { bytesRead = this.sslStream.Read(this.buffer, bytesInBuffer, this.buffer.Length - bytesInBuffer); } catch (IOException e) { Error = e.Message; Debug.WriteLine("ImapClient.FetchHeaders(): IO Exception occured while reading from " + Account.ImapServerName + "(" + account.AccountName + ").\n" + e.Message); return(null); } catch (Exception e) { Error = e.Message; Debug.WriteLine("ImapClient.FetchHeaders(): Exception occured while reading from " + Account.ImapServerName + "(" + account.AccountName + ").\n" + e.Message); return(null); } string strBuffer = Encoding.ASCII.GetString(this.buffer, 0, bytesInBuffer + bytesRead); Match match; string remainder = strBuffer; bool doneMatching = false; while (!doneMatching) { // Each untagged response item represents one message. string unTaggedResponsePattern = "(^|\r\n)(\\* (.*\r\n)*?)(\\*|" + tag + ") "; match = Regex.Match(remainder, unTaggedResponsePattern); if (match.Success) { string untaggedResponse = match.Groups[2].ToString(); Message message = ImapParser.ParseFetchHeader(untaggedResponse); if (message != null) { message.AccountName = Account.AccountName; message.MailboxPath = SelectedMailboxName; messages.Add(message); } remainder = remainder.Substring(match.Groups[2].ToString().Length); } else { // Did not find an untagged response. Check if it is a tagged response. string taggedResponsePattern = "^" + tag + " .*\r\n"; match = Regex.Match(remainder, taggedResponsePattern); if (match.Success) { doneMatching = true; doneFetching = true; } else { // Neither untagged nor tagged response was found. Maybe only a portion of // the response was read. Move the dangling bytes to the front of the buffer // for the next read. doneMatching = true; if (remainder.Length > 0) { for (int i = 0; i < remainder.Length; ++i) { this.buffer[i] = (byte)remainder[i]; } bytesInBuffer = remainder.Length; } } } } } return(messages); }