/* * /// <summary> * /// Raises event 'Search'. * /// </summary> * /// <param name="session">IMAP session what calls this search.</param> * /// <param name="folder">Folder what messages to search.</param> * /// <param name="matcher">Matcher what must be used to check if message matches searching criterial.</param> * /// <returns></returns> * internal IMAP_eArgs_Search OnSearch(IMAP_Session session,string folder,IMAP_SearchMatcher matcher) * { * IMAP_eArgs_Search eArgs = new IMAP_eArgs_Search(session,folder,matcher); * if(this.Search != null){ * this.Search(session,eArgs); * } * * return eArgs; * }*/ #endregion #region function OnStoreMessageFlags /// <summary> /// Raises event 'StoreMessageFlags'. /// </summary> /// <param name="session">Reference to IMAP session.</param> /// <param name="msg">Message which flags to store.</param> /// <returns></returns> internal string OnStoreMessageFlags(IMAP_Session session, IMAP_Message msg) { Message_EventArgs eArgs = new Message_EventArgs(IMAP_Utils.Decode_IMAP_UTF7_String(session.SelectedMailbox), msg); if (this.StoreMessageFlags != null) { this.StoreMessageFlags(session, eArgs); } return(eArgs.ErrorText); }
/// <summary> /// Raises event 'CopyMessage'. /// </summary> /// <param name="session">Reference to IMAP session.</param> /// <param name="msg">Message which to copy.</param> /// <param name="location">New message location.</param> /// <returns></returns> internal string OnCopyMessage(IMAP_Session session, IMAP_Message msg, string location) { Message_EventArgs eArgs = new Message_EventArgs(IMAP_Utils.Decode_IMAP_UTF7_String(session.SelectedMailbox), msg, location); if (this.CopyMessage != null) { this.CopyMessage(session, eArgs); } return(eArgs.ErrorText); }
/// <summary> /// Raises event 'DeleteMessage'. /// </summary> /// <param name="session">Reference to IMAP session.</param> /// <param name="message">Message which to delete.</param> /// <returns></returns> internal string OnDeleteMessage(IMAP_Session session, IMAP_Message message) { Message_EventArgs eArgs = new Message_EventArgs(IMAP_Utils.Decode_IMAP_UTF7_String(session.SelectedMailbox), message); if (this.DeleteMessage != null) { this.DeleteMessage(session, eArgs); } return(eArgs.ErrorText); }
/// <summary> /// Adds folder to folders list. /// </summary> /// <param name="folder">Full path to folder, path separator = '/'. Eg. Inbox/myFolder .</param> /// <param name="selectable">Gets or sets if folder is selectable(SELECT command can select this folder).</param> public void Add(string folder, bool selectable) { folder = folder.Replace("\\", "/"); string folderPattern = m_RefName + m_Mailbox; if (m_RefName != "" && !m_RefName.EndsWith("/") && !m_Mailbox.StartsWith("/")) { folderPattern = m_RefName + "/" + m_Mailbox; } if (FolderMatches(folderPattern, IMAP_Utils.Decode_IMAP_UTF7_String(folder))) { m_Mailboxes.Add(new IMAP_Folder(folder, selectable)); } }
/// <summary> /// Updates IMAP message flags. /// </summary> /// <param name="setType">Flags set type.</param> /// <param name="flags">IMAP message flags.</param> /// <exception cref="ArgumentNullException">Is raised when <b>flags</b> is null reference.</exception> internal void UpdateFlags(IMAP_Flags_SetType setType, string[] flags) { if (flags == null) { throw new ArgumentNullException("flags"); } if (setType == IMAP_Flags_SetType.Add) { m_pFlags = IMAP_Utils.MessageFlagsAdd(m_pFlags, flags); } else if (setType == IMAP_Flags_SetType.Remove) { m_pFlags = IMAP_Utils.MessageFlagsRemove(m_pFlags, flags); } else { m_pFlags = flags; } }
/// <summary> /// Gets if specified message matches with this class search-key. /// </summary> /// <param name="no">IMAP message sequence number.</param> /// <param name="uid">IMAP message UID.</param> /// <param name="size">IMAP message size in bytes.</param> /// <param name="internalDate">IMAP message INTERNALDATE (dateTime when server stored message).</param> /// <param name="flags">IMAP message flags.</param> /// <param name="message">Mime message main header only.</param> /// <param name="bodyText">Message body text.</param> /// <returns></returns> public bool Match(long no, long uid, long size, DateTime internalDate, IMAP_MessageFlags flags, Mail_Message message, string bodyText) { #region ALL // ALL // All messages in the mailbox; the default initial key for ANDing. if (m_SearchKeyName == "ALL") { return(true); } #endregion #region BEFORE // BEFORE <date> // Messages whose internal date (disregarding time and timezone) // is earlier than the specified date. else if (m_SearchKeyName == "BEFORE") { if (internalDate.Date < (DateTime)m_SearchKeyValue) { return(true); } } #endregion #region BODY // BODY <string> // Messages that contain the specified string in the body of the message. // // NOTE: Compare must be done on decoded header and decoded body of message. // In all search keys that use strings, a message matches the key if // the string is a substring of the field. The matching is case-insensitive. else if (m_SearchKeyName == "BODY") { string val = bodyText; if (val != null && val.ToLower().IndexOf(((string)m_SearchKeyValue).ToLower()) > -1) { return(true); } } #endregion #region HEADER // HEADER <field-name> <string> // Messages that have a header with the specified field-name (as // defined in [RFC-2822]) and that contains the specified string // in the text of the header (what comes after the colon). If the // string to search is zero-length, this matches all messages that // have a header line with the specified field-name regardless of // the contents. // // NOTE: Compare must be done on decoded header field value. // In all search keys that use strings, a message matches the key if // the string is a substring of the field. The matching is case-insensitive. else if (m_SearchKeyName == "HEADER") { string[] headerField_value = (string[])m_SearchKeyValue; // If header field ends with ":", remove it. if (headerField_value[0].EndsWith(":")) { headerField_value[0] = headerField_value[0].Substring(0, headerField_value[0].Length - 1); } if (string.IsNullOrEmpty(headerField_value[1])) { return(true); } else { MIME_h h = message.Header.GetFirst(headerField_value[0]); if (h == null) { return(false); } else { if (h.ValueToString().ToLower().IndexOf(headerField_value[1].ToLower()) > -1) { return(true); } } } } #endregion #region KEYWORD // KEYWORD <flag> // Messages with the specified keyword flag set. else if (m_SearchKeyName == "KEYWORD") { if ((flags & IMAP_Utils.ParseMessageFlags((string)m_SearchKeyValue)) != 0) { return(true); } } #endregion #region LARGER // LARGER <n> // Messages with an [RFC-2822] size larger than the specified number of octets. else if (m_SearchKeyName == "LARGER") { if (size > (long)m_SearchKeyValue) { return(true); } } #endregion #region NOT // NOT <search-key> or (<search-key> <search-key> ...)(SearchGroup) // Messages that do not match the specified search key. else if (m_SearchKeyName == "NOT") { return(!SearchGroup.Match_Key_Value(m_SearchKeyValue, no, uid, size, internalDate, flags, message, bodyText)); } #endregion #region ON // ON <date> // Messages whose internal date (disregarding time and timezone) // is within the specified date. else if (m_SearchKeyName == "ON") { if (internalDate.Date == (DateTime)m_SearchKeyValue) { return(true); } } #endregion #region OR // OR <search-key1> <search-key2> - SearckKey can be parenthesis list of keys ! // Messages that match either search key. else if (m_SearchKeyName == "OR") { object serachKey1 = ((object[])m_SearchKeyValue)[0]; object serachKey2 = ((object[])m_SearchKeyValue)[1]; if (SearchGroup.Match_Key_Value(serachKey1, no, uid, size, internalDate, flags, message, bodyText) || SearchGroup.Match_Key_Value(serachKey2, no, uid, size, internalDate, flags, message, bodyText)) { return(true); } } #endregion #region SENTBEFORE // SENTBEFORE <date> // Messages whose [RFC-2822] Date: header (disregarding time and // timezone) is earlier than the specified date. else if (m_SearchKeyName == "SENTBEFORE") { if (message.Date.Date < (DateTime)m_SearchKeyValue) { return(true); } } #endregion #region SENTON // SENTON <date> // Messages whose [RFC-2822] Date: header (disregarding time and // timezone) is within the specified date. else if (m_SearchKeyName == "SENTON") { if (message.Date.Date == (DateTime)m_SearchKeyValue) { return(true); } } #endregion #region SENTSINCE // SENTSINCE <date> // Messages whose [RFC-2822] Date: header (disregarding time and // timezone) is within or later than the specified date. else if (m_SearchKeyName == "SENTSINCE") { if (message.Date.Date >= (DateTime)m_SearchKeyValue) { return(true); } } #endregion #region SINCE // SINCE <date> // Messages whose internal date (disregarding time and timezone) // is within or later than the specified date. else if (m_SearchKeyName == "SINCE") { if (internalDate.Date >= (DateTime)m_SearchKeyValue) { return(true); } } #endregion #region SMALLER // SMALLER <n> // Messages with an [RFC-2822] size smaller than the specified number of octets. else if (m_SearchKeyName == "SMALLER") { if (size < (long)m_SearchKeyValue) { return(true); } } #endregion #region TEXT // TEXT <string> // Messages that contain the specified string in the header or body of the message. // // NOTE: Compare must be done on decoded header and decoded body of message. // In all search keys that use strings, a message matches the key if // the string is a substring of the field. The matching is case-insensitive. else if (m_SearchKeyName == "TEXT") { // See body first string val = bodyText; if (val != null && val.ToLower().IndexOf(((string)m_SearchKeyValue).ToLower()) > -1) { return(true); } // If we reach so far, that means body won't contain specified text and we need to check header. foreach (MIME_h headerField in message.Header) { if (headerField.ToString().ToLower().IndexOf(((string)m_SearchKeyValue).ToLower()) > -1) { return(true); } } } #endregion #region UID // UID <sequence set> // Messages with unique identifiers corresponding to the specified // unique identifier set. Sequence set ranges are permitted. else if (m_SearchKeyName == "UID") { return(((IMAP_SequenceSet)m_SearchKeyValue).Contains(uid)); } #endregion #region UNKEYWORD // UNKEYWORD <flag> // Messages that do not have the specified keyword flag set. else if (m_SearchKeyName == "UNKEYWORD") { if ((flags & IMAP_Utils.ParseMessageFlags((string)m_SearchKeyValue)) == 0) { return(true); } } #endregion #region SEQUENCESET // <sequence set> // Messages with message sequence numbers corresponding to the // specified message sequence number set. else if (m_SearchKeyName == "SEQUENCESET") { return(((IMAP_SequenceSet)m_SearchKeyValue).Contains(no)); } #endregion return(false); }
/// <summary> /// Parses one search key from current position. Returns null if there isn't any search key left. /// </summary> /// <param name="reader"></param> public static SearchKey Parse(StringReader reader) { string searchKeyName = ""; object searchKeyValue = null; //Remove spaces from string start reader.ReadToFirstChar(); // Search keyname is always 1 word string word = reader.ReadWord(); if (word == null) { return(null); } word = word.ToUpper().Trim(); //Remove spaces from string start reader.ReadToFirstChar(); #region ALL // ALL // All messages in the mailbox; the default initial key for ANDing. if (word == "ALL") { searchKeyName = "ALL"; } #endregion #region ANSWERED // ANSWERED // Messages with the \Answered flag set. else if (word == "ANSWERED") { // We internally use KEYWORD ANSWERED searchKeyName = "KEYWORD"; searchKeyValue = "ANSWERED"; } #endregion #region BCC // BCC <string> // Messages that contain the specified string in the envelope structure's BCC field. else if (word == "BCC") { // We internally use HEADER "BCC:" "value" searchKeyName = "HEADER"; // Read <string> string val = ReadString(reader); if (val != null) { searchKeyValue = new string[] { "BCC:", TextUtils.UnQuoteString(val) }; } else { throw new Exception("BCC <string> value is missing !"); } } #endregion #region BEFORE // BEFORE <date> // Messages whose internal date (disregarding time and timezone) is earlier than the specified date. else if (word == "BEFORE") { searchKeyName = "BEFORE"; // Read <date> string val = reader.QuotedReadToDelimiter(' '); if (val != null) { // Parse date try{ searchKeyValue = IMAP_Utils.ParseDate(TextUtils.UnQuoteString(val)); } // Invalid date catch { throw new Exception("Invalid BEFORE <date> value '" + val + "', valid date syntax: {dd-MMM-yyyy} !"); } } else { throw new Exception("BEFORE <date> value is missing !"); } } #endregion #region BODY // BODY <string> // Messages that contain the specified string in the body of the message. else if (word == "BODY") { searchKeyName = "BODY"; string val = ReadString(reader); if (val != null) { searchKeyValue = val; } else { throw new Exception("BODY <string> value is missing !"); } } #endregion #region CC // CC <string> // Messages that contain the specified string in the envelope structure's CC field. else if (word == "CC") { // We internally use HEADER "CC:" "value" searchKeyName = "HEADER"; // Read <string> string val = ReadString(reader); if (val != null) { searchKeyValue = new string[] { "CC:", TextUtils.UnQuoteString(val) }; } else { throw new Exception("CC <string> value is missing !"); } } #endregion #region DELETED // DELETED // Messages with the \Deleted flag set. else if (word == "DELETED") { // We internally use KEYWORD DELETED searchKeyName = "KEYWORD"; searchKeyValue = "DELETED"; } #endregion #region DRAFT // DRAFT // Messages with the \Draft flag set. else if (word == "DRAFT") { // We internally use KEYWORD DRAFT searchKeyName = "KEYWORD"; searchKeyValue = "DRAFT"; } #endregion #region FLAGGED // FLAGGED // Messages with the \Flagged flag set. else if (word == "FLAGGED") { // We internally use KEYWORD FLAGGED searchKeyName = "KEYWORD"; searchKeyValue = "FLAGGED"; } #endregion #region FROM // FROM <string> // Messages that contain the specified string in the envelope structure's FROM field. else if (word == "FROM") { // We internally use HEADER "FROM:" "value" searchKeyName = "HEADER"; // Read <string> string val = ReadString(reader); if (val != null) { searchKeyValue = new string[] { "FROM:", TextUtils.UnQuoteString(val) }; } else { throw new Exception("FROM <string> value is missing !"); } } #endregion #region HEADER // HEADER <field-name> <string> // Messages that have a header with the specified field-name (as // defined in [RFC-2822]) and that contains the specified string // in the text of the header (what comes after the colon). If the // string to search is zero-length, this matches all messages that // have a header line with the specified field-name regardless of // the contents. else if (word == "HEADER") { searchKeyName = "HEADER"; // Read <field-name> string fieldName = ReadString(reader); if (fieldName != null) { fieldName = TextUtils.UnQuoteString(fieldName); } else { throw new Exception("HEADER <field-name> value is missing !"); } // Read <string> string val = ReadString(reader); if (val != null) { searchKeyValue = new string[] { fieldName, TextUtils.UnQuoteString(val) }; } else { throw new Exception("(HEADER <field-name>) <string> value is missing !"); } } #endregion #region KEYWORD // KEYWORD <flag> // Messages with the specified keyword flag set. else if (word == "KEYWORD") { searchKeyName = "KEYWORD"; // Read <flag> string val = reader.QuotedReadToDelimiter(' '); if (val != null) { searchKeyValue = TextUtils.UnQuoteString(val); } else { throw new Exception("KEYWORD <flag> value is missing !"); } } #endregion #region LARGER // LARGER <n> // Messages with an [RFC-2822] size larger than the specified number of octets. else if (word == "LARGER") { searchKeyName = "LARGER"; // Read <n> string val = reader.QuotedReadToDelimiter(' '); if (val != null) { // Parse <n> - must be integer value try{ searchKeyValue = Convert.ToInt64(TextUtils.UnQuoteString(val)); } // Invalid <n> catch { throw new Exception("Invalid LARGER <n> value '" + val + "', it must be numeric value !"); } } else { throw new Exception("LARGER <n> value is missing !"); } } #endregion #region NEW // NEW // Messages that have the \Recent flag set but not the \Seen flag. // This is functionally equivalent to "(RECENT UNSEEN)". else if (word == "NEW") { // We internally use KEYWORD RECENT searchKeyName = "KEYWORD"; searchKeyValue = "RECENT"; } #endregion #region NOT // NOT <search-key> or (<search-key> <search-key> ...)(SearchGroup) // Messages that do not match the specified search key. else if (word == "NOT") { searchKeyName = "NOT"; object searchItem = SearchGroup.ParseSearchKey(reader); if (searchItem != null) { searchKeyValue = searchItem; } else { throw new Exception("Required NOT <search-key> isn't specified !"); } } #endregion #region OLD // OLD // Messages that do not have the \Recent flag set. This is // functionally equivalent to "NOT RECENT" (as opposed to "NOT NEW"). else if (word == "OLD") { // We internally use UNKEYWORD RECENT searchKeyName = "UNKEYWORD"; searchKeyValue = "RECENT"; } #endregion #region ON // ON <date> // Messages whose internal date (disregarding time and timezone) is within the specified date. else if (word == "ON") { searchKeyName = "ON"; // Read <date> string val = reader.QuotedReadToDelimiter(' '); if (val != null) { // Parse date try{ searchKeyValue = IMAP_Utils.ParseDate(TextUtils.UnQuoteString(val)); } // Invalid date catch { throw new Exception("Invalid ON <date> value '" + val + "', valid date syntax: {dd-MMM-yyyy} !"); } } else { throw new Exception("ON <date> value is missing !"); } } #endregion #region OR // OR <search-key1> <search-key2> - SearckKey can be parenthesis list of keys ! // Messages that match either search key. else if (word == "OR") { searchKeyName = "OR"; //--- <search-key1> ----------------------------------------------------// object searchKey1 = SearchGroup.ParseSearchKey(reader); if (searchKey1 == null) { throw new Exception("Required OR <search-key1> isn't specified !"); } //----------------------------------------------------------------------// //--- <search-key2> ----------------------------------------------------// object searchKey2 = SearchGroup.ParseSearchKey(reader); if (searchKey2 == null) { throw new Exception("Required (OR <search-key1>) <search-key2> isn't specified !"); } //-----------------------------------------------------------------------// searchKeyValue = new object[] { searchKey1, searchKey2 }; } #endregion #region RECENT // RECENT // Messages that have the \Recent flag set. else if (word == "RECENT") { // We internally use KEYWORD RECENT searchKeyName = "KEYWORD"; searchKeyValue = "RECENT"; } #endregion #region SEEN // SEEN // Messages that have the \Seen flag set. else if (word == "SEEN") { // We internally use KEYWORD SEEN searchKeyName = "KEYWORD"; searchKeyValue = "SEEN"; } #endregion #region SENTBEFORE // SENTBEFORE <date> // Messages whose [RFC-2822] Date: header (disregarding time and // timezone) is earlier than the specified date. else if (word == "SENTBEFORE") { searchKeyName = "SENTBEFORE"; // Read <date> string val = reader.QuotedReadToDelimiter(' '); if (val != null) { // Parse date try{ searchKeyValue = IMAP_Utils.ParseDate(TextUtils.UnQuoteString(val)); } // Invalid date catch { throw new Exception("Invalid SENTBEFORE <date> value '" + val + "', valid date syntax: {dd-MMM-yyyy} !"); } } else { throw new Exception("SENTBEFORE <date> value is missing !"); } } #endregion #region SENTON // SENTON <date> // Messages whose [RFC-2822] Date: header (disregarding time and // timezone) is within the specified date. else if (word == "SENTON") { searchKeyName = "SENTON"; // Read <date> string val = reader.QuotedReadToDelimiter(' '); if (val != null) { // Parse date try{ searchKeyValue = IMAP_Utils.ParseDate(TextUtils.UnQuoteString(val)); } // Invalid date catch { throw new Exception("Invalid SENTON <date> value '" + val + "', valid date syntax: {dd-MMM-yyyy} !"); } } else { throw new Exception("SENTON <date> value is missing !"); } } #endregion #region SENTSINCE // SENTSINCE <date> // Messages whose [RFC-2822] Date: header (disregarding time and // timezone) is within or later than the specified date. else if (word == "SENTSINCE") { searchKeyName = "SENTSINCE"; // Read <date> string val = reader.QuotedReadToDelimiter(' '); if (val != null) { // Parse date try{ searchKeyValue = IMAP_Utils.ParseDate(TextUtils.UnQuoteString(val)); } // Invalid date catch { throw new Exception("Invalid SENTSINCE <date> value '" + val + "', valid date syntax: {dd-MMM-yyyy} !"); } } else { throw new Exception("SENTSINCE <date> value is missing !"); } } #endregion #region SINCE // SINCE <date> // Messages whose internal date (disregarding time and timezone) // is within or later than the specified date. else if (word == "SINCE") { searchKeyName = "SINCE"; // Read <date> string val = reader.ReadWord(); if (val != null) { // Parse date try{ searchKeyValue = IMAP_Utils.ParseDate(TextUtils.UnQuoteString(val)); } // Invalid date catch { throw new Exception("Invalid SINCE <date> value '" + val + "', valid date syntax: {dd-MMM-yyyy} !"); } } else { throw new Exception("SINCE <date> value is missing !"); } } #endregion #region SMALLER // SMALLER <n> // Messages with an [RFC-2822] size smaller than the specified number of octets. else if (word == "SMALLER") { searchKeyName = "SMALLER"; // Read <n> string val = reader.QuotedReadToDelimiter(' '); if (val != null) { val = TextUtils.UnQuoteString(val); // Parse <n> - must be integer value try{ searchKeyValue = Convert.ToInt64(val); } // Invalid <n> catch { throw new Exception("Invalid SMALLER <n> value '" + val + "', it must be numeric value !"); } } else { throw new Exception("SMALLER <n> value is missing !"); } } #endregion #region SUBJECT // SUBJECT <string> // Messages that contain the specified string in the envelope structure's SUBJECT field. else if (word == "SUBJECT") { // We internally use HEADER "SUBJECT:" "value" searchKeyName = "HEADER"; // Read <string> string val = ReadString(reader); if (val != null) { searchKeyValue = new string[] { "SUBJECT:", TextUtils.UnQuoteString(val) }; } else { throw new Exception("SUBJECT <string> value is missing !"); } } #endregion #region TEXT // TEXT <string> // Messages that contain the specified string in the header or body of the message. else if (word == "TEXT") { searchKeyName = "TEXT"; string val = ReadString(reader); if (val != null) { searchKeyValue = val; } else { throw new Exception("TEXT <string> value is missing !"); } } #endregion #region TO // TO <string> // Messages that contain the specified string in the envelope structure's TO field. else if (word == "TO") { // We internally use HEADER "TO:" "value" searchKeyName = "HEADER"; // Read <string> string val = ReadString(reader); if (val != null) { searchKeyValue = new string[] { "TO:", TextUtils.UnQuoteString(val) }; } else { throw new Exception("TO <string> value is missing !"); } } #endregion #region UID // UID <sequence set> // Messages with unique identifiers corresponding to the specified // unique identifier set. Sequence set ranges are permitted. else if (word == "UID") { searchKeyName = "UID"; // Read <sequence set> string val = reader.QuotedReadToDelimiter(' '); if (val != null) { try{ IMAP_SequenceSet sequenceSet = new IMAP_SequenceSet(); sequenceSet.Parse(TextUtils.UnQuoteString(val), long.MaxValue); searchKeyValue = sequenceSet; } catch { throw new Exception("Invalid UID <sequence-set> value '" + val + "' !"); } } else { throw new Exception("UID <sequence-set> value is missing !"); } } #endregion #region UNANSWERED // UNANSWERED // Messages that do not have the \Answered flag set. else if (word == "UNANSWERED") { // We internally use UNKEYWORD SEEN searchKeyName = "UNKEYWORD"; searchKeyValue = "ANSWERED"; } #endregion #region UNDELETED // UNDELETED // Messages that do not have the \Deleted flag set. else if (word == "UNDELETED") { // We internally use UNKEYWORD UNDELETED searchKeyName = "UNKEYWORD"; searchKeyValue = "DELETED"; } #endregion #region UNDRAFT // UNDRAFT // Messages that do not have the \Draft flag set. else if (word == "UNDRAFT") { // We internally use UNKEYWORD UNDRAFT searchKeyName = "UNKEYWORD"; searchKeyValue = "DRAFT"; } #endregion #region UNFLAGGED // UNFLAGGED // Messages that do not have the \Flagged flag set. else if (word == "UNFLAGGED") { // We internally use UNKEYWORD UNFLAGGED searchKeyName = "UNKEYWORD"; searchKeyValue = "FLAGGED"; } #endregion #region UNKEYWORD // UNKEYWORD <flag> // Messages that do not have the specified keyword flag set. else if (word == "UNKEYWORD") { searchKeyName = "UNKEYWORD"; // Read <flag> string val = reader.QuotedReadToDelimiter(' '); if (val != null) { searchKeyValue = TextUtils.UnQuoteString(val); } else { throw new Exception("UNKEYWORD <flag> value is missing !"); } } #endregion #region UNSEEN // UNSEEN // Messages that do not have the \Seen flag set. else if (word == "UNSEEN") { // We internally use UNKEYWORD UNSEEN searchKeyName = "UNKEYWORD"; searchKeyValue = "SEEN"; } #endregion #region Unknown or SEQUENCESET // Unkown keyword or <sequence set> else { // DUMMY palce(bad design) in IMAP. // Active keyword can be <sequence set> or bad keyword, there is now way to distinguish what is meant. // Why they don't key work SEQUENCESET <sequence set> ? // <sequence set> // Messages with message sequence numbers corresponding to the // specified message sequence number set. // Just try if it can be parsed as sequence-set try{ IMAP_SequenceSet sequenceSet = new IMAP_SequenceSet(); sequenceSet.Parse(word, long.MaxValue); searchKeyName = "SEQUENCESET"; searchKeyValue = sequenceSet; } // This isn't vaild sequnce-set value catch { throw new Exception("Invalid search key or <sequnce-set> value '" + word + "' !"); } } #endregion // REMOVE ME: // Console.WriteLine(searchKeyName + " : " + Convert.ToString(searchKeyValue)); return(new SearchKey(searchKeyName, searchKeyValue)); }