/// <summary> /// Initialises a new instance so that it represents a subset of the <see cref="eSectionTextPart.header"/>. /// </summary> /// <param name="pPart">A dot separated list of integers specifying the body-part, or <see langword="null"/> for the whole message</param> /// <param name="pNames">Must not be <see langword="null"/> nor empty.</param> /// <param name="pNot"><see langword="true"/> to represent all header fields except those specified, <see langword="false"/> to represent only the header fields specified.</param> public cSection(string pPart, cHeaderFieldNames pNames, bool pNot = false) { if (pPart != null && !ZValidPart(pPart)) { throw new ArgumentOutOfRangeException(nameof(pPart)); } Part = pPart; if (pNot) { TextPart = eSectionTextPart.headerfieldsnot; } else { TextPart = eSectionTextPart.headerfields; } if (pNames == null) { throw new ArgumentNullException(nameof(pNames)); } if (pNames.Count == 0) { throw new ArgumentOutOfRangeException(nameof(pNames)); } Names = pNames; }
/// <summary> /// Initialises a new instance so that it represents an entire body-part. /// </summary> /// <param name="pPart">A dot separated list of integers specifying the body-part, or <see langword="null"/> for the whole message</param> /// <remarks> /// <see cref="TextPart"/> is set to <see cref="eSectionTextPart.all"/>, <see cref="Names"/> to <see langword="null"/>. /// </remarks> public cSection(string pPart) { if (pPart != null && !ZValidPart(pPart)) { throw new ArgumentOutOfRangeException(nameof(pPart)); } Part = pPart; TextPart = eSectionTextPart.all; Names = null; }
/// <summary> /// Returns the header field names from the specified collection that this instance has not been populated with (case insensitive). /// </summary> /// <param name="pNames"></param> /// <returns></returns> public cHeaderFieldNames Missing(cHeaderFieldNames pNames) { if (mNot) { return(pNames.Intersect(mNames)); } else { return(pNames.Except(mNames)); } }
/// <summary> /// Determines whether the collection has not been populated with header fields of any of the names specified (case insensitive). /// </summary> /// <param name="pNames"></param> /// <returns></returns> /// <remarks> /// <see langword="false"/> does not mean that there are any header fields of the specified names in the collection. /// </remarks> public bool ContainsNone(cHeaderFieldNames pNames) { if (mNot) { return(mNames.Contains(pNames)); } foreach (var lName in pNames) { if (mNames.Contains(lName)) { return(false); } } return(true); }
/// <summary> /// Initialises a new instance using the specified <see cref="cMessage"/> properties. /// </summary> /// <param name="pProperties">The message properties to cache the backing data for.</param> public cMessageCacheItems(fMessageProperties pProperties) { Attributes = 0; // see comments elsewhere as to why mdnsent is commented out if ((pProperties & (fMessageProperties.flags | fMessageProperties.answered | fMessageProperties.flagged | fMessageProperties.deleted | fMessageProperties.seen | fMessageProperties.draft | fMessageProperties.recent | /* fMessageProperties.mdnsent | */ fMessageProperties.forwarded | fMessageProperties.submitpending | fMessageProperties.submitted)) != 0) { Attributes |= fMessageCacheAttributes.flags; } if ((pProperties & (fMessageProperties.envelope | fMessageProperties.sent | fMessageProperties.subject | fMessageProperties.basesubject | fMessageProperties.from | fMessageProperties.sender | fMessageProperties.replyto | fMessageProperties.to | fMessageProperties.cc | fMessageProperties.bcc | fMessageProperties.inreplyto | fMessageProperties.messageid)) != 0) { Attributes |= fMessageCacheAttributes.envelope; } if ((pProperties & fMessageProperties.received) != 0) { Attributes |= fMessageCacheAttributes.received; } if ((pProperties & fMessageProperties.size) != 0) { Attributes |= fMessageCacheAttributes.size; } if ((pProperties & fMessageProperties.bodystructure | fMessageProperties.attachments | fMessageProperties.plaintextsizeinbytes) != 0) { Attributes |= fMessageCacheAttributes.bodystructure; } if ((pProperties & fMessageProperties.uid) != 0) { Attributes |= fMessageCacheAttributes.uid; } if ((pProperties & fMessageProperties.modseq) != 0) { Attributes |= fMessageCacheAttributes.modseq; } cHeaderFieldNameList lNames = new cHeaderFieldNameList(); if ((pProperties & fMessageProperties.references) != 0) { lNames.Add(kHeaderFieldName.References); } if ((pProperties & fMessageProperties.importance) != 0) { lNames.Add(kHeaderFieldName.Importance); } Names = new cHeaderFieldNames(lNames); }
/// <summary> /// Initialises a new instance so that it represents a whole text part. /// </summary> /// <param name="pPart">A dot separated list of integers specifying the body-part, or <see langword="null"/> for the whole message</param> /// <param name="pTextPart">May be <see cref="eSectionTextPart.all"/>, <see cref="eSectionTextPart.header"/>, <see cref="eSectionTextPart.text"/> or <see cref="eSectionTextPart.mime"/> (<see cref="eSectionTextPart.mime"/> only if <paramref name="pPart"/> is not <see langword="null"/>).</param> public cSection(string pPart, eSectionTextPart pTextPart) { if (pPart != null && !ZValidPart(pPart)) { throw new ArgumentOutOfRangeException(nameof(pPart)); } Part = pPart; if (pTextPart == eSectionTextPart.headerfields || pTextPart == eSectionTextPart.headerfieldsnot) { throw new ArgumentOutOfRangeException(nameof(pTextPart)); } if (pPart == null && pTextPart == eSectionTextPart.mime) { throw new ArgumentOutOfRangeException(nameof(pTextPart)); } TextPart = pTextPart; Names = null; }
/// <summary> /// Initialises a new instance using the specified IMAP message attributes and header field names. /// </summary> /// <param name="pAttributes"></param> /// <param name="pNames">Can't be <see langword="null"/>, may be empty.</param> public cMessageCacheItems(fMessageCacheAttributes pAttributes, cHeaderFieldNames pNames) { Attributes = pAttributes; Names = pNames ?? throw new ArgumentNullException(nameof(pNames)); }
internal static void _Tests(cTrace.cContext pParentContext) { var lContext = pParentContext.NewMethod(nameof(cHeaderFields), nameof(_Tests)); cStrings lStrings; cHeaderFieldNames lABCDE = new cHeaderFieldNames("a", "B", "c", "D", "e"); cHeaderFieldNames lDEFGH = new cHeaderFieldNames("f", "g", "h", "D", "e"); cHeaderFieldNames lGHIJK = new cHeaderFieldNames("i", "g", "h", "j", "K"); var lBytes = new cBytes( "angus: value of angus\r\n" + "fred : value of fred \r\n" + "charlie \t : value \r\n \t of \r\n charlie \t\t \r\n" + "message-id : <*****@*****.**> \r\n" + "MESSAGE-id : <1234 @ local(blah) .machine .example> \r\n" + "IN-reply-TO: <*****@*****.**><*****@*****.**>\r\n\t<*****@*****.**>\r\n" + "REfEReNCeS:\r\n\t<*****@*****.**>\r\n\t< \"12345\" @ local(blah) .machine .example> \r\n" + "Importance: low\r\n" + "anotherone: just in case\r\n" + "\r\n" + "check: stop\r\n"); if (!TryConstruct(lBytes, out var lFields)) { throw new cTestsException($"{nameof(cHeaderFields)}.1.1"); } if (lFields.Count != 9) { throw new cTestsException($"{nameof(cHeaderFields)}.1.1.1"); } if (!lFields.Contains("a")) { throw new cTestsException($"{nameof(cHeaderFields)}.1.2"); } if (!lFields.Contains(lABCDE)) { throw new cTestsException($"{nameof(cHeaderFields)}.1.3"); } if (!lFields.Contains(lDEFGH)) { throw new cTestsException($"{nameof(cHeaderFields)}.1.4"); } if (!lFields.Contains(lGHIJK)) { throw new cTestsException($"{nameof(cHeaderFields)}.1.5"); } if (lFields.ContainsNone(lABCDE) || lFields.ContainsNone(lDEFGH) || lFields.ContainsNone(lGHIJK)) { throw new cTestsException($"{nameof(cHeaderFields)}.1.6"); } if (lFields.Missing(lABCDE).Count != 0 || lFields.Missing(lDEFGH).Count != 0) { throw new cTestsException($"{nameof(cHeaderFields)}.1.7"); } if (cTools.ASCIIBytesToString(lFields.FirstNamed("fred").Value) != " value of fred ") { throw new cTestsException($"{nameof(cHeaderFields)}.1.8"); } if (lFields.FirstNamed("a") != null) { throw new cTestsException($"{nameof(cHeaderFields)}.1.9"); } if (lFields.AllNamed("fred").Count() != 1) { throw new cTestsException($"{nameof(cHeaderFields)}.1.10"); } if (lFields.AllNamed("a").Count() != 0) { throw new cTestsException($"{nameof(cHeaderFields)}.1.11"); } if (lFields.AllNamed("mEsSaGe-ID").Count() != 2) { throw new cTestsException($"{nameof(cHeaderFields)}.1.12"); } //if (!lFields.All("mEsSaGe-ID").All(h => h is cHeaderFieldMsgId lMsgId && lMsgId.MsgId == "*****@*****.**")) throw new cTestsException($"{nameof(cHeaderFields)}.1.13"); //lStrings = (lFields.First(cHeaderFieldNames.InReplyTo) as cHeaderFieldMsgIds)?.MsgIds; //if (lStrings.Count != 3 || !lStrings.Contains("*****@*****.**") || !lStrings.Contains("*****@*****.**") || !lStrings.Contains("*****@*****.**")) throw new cTestsException($"{nameof(cHeaderFields)}.1.15"); lStrings = lFields.References; if (lStrings.Count != 2 || !lStrings.Contains("*****@*****.**") || !lStrings.Contains("*****@*****.**")) { throw new cTestsException($"{nameof(cHeaderFields)}.1.16"); } if (lFields.Importance != eImportance.low) { throw new cTestsException($"{nameof(cHeaderFields)}.1.17"); } if (!lFields.Contains("check") || lFields.AllNamed("check").Count() != 0) { throw new cTestsException($"{nameof(cHeaderFields)}.1.18"); } lBytes = new cBytes("a: 1\r\nc: 2\r\nc: two\r\ne: 3\r\n\r\n"); if (!TryConstruct(lABCDE, false, lBytes, out var lFieldsABCDE)) { throw new cTestsException($"{nameof(cHeaderFields)}.2.1"); } if (!TryConstruct(lABCDE, false, lBytes, out var lFieldsABCDE2)) { throw new cTestsException($"{nameof(cHeaderFields)}.2.1.1"); } lBytes = new cBytes("e: 3\r\ng: 4\r\ng: four\r\n\r\n"); if (!TryConstruct(lDEFGH, false, lBytes, out var lFieldsDEFGH)) { throw new cTestsException($"{nameof(cHeaderFields)}.2.2"); } lBytes = new cBytes("g: 4\r\ni: 5\r\nk: 6\r\nk: six\r\n"); if (!TryConstruct(lGHIJK, false, lBytes, out var lFieldsGHIJK)) { throw new cTestsException($"{nameof(cHeaderFields)}.2.3"); } lBytes = new cBytes( "Importance: normal\r\n" + "message-id : <[email protected] \r\n" + "IN-reply-TO: <*****@*****.**><[email protected]\r\n\t<*****@*****.**>\r\n" + "g: 4\r\ng: four\r\ni: 5\r\nk: 6\r\nk: six\r\n"); if (!TryConstruct(lABCDE, true, lBytes, out var lNotABCDE)) { throw new cTestsException($"{nameof(cHeaderFields)}.2.4"); } lBytes = new cBytes( "Importance: high\r\n" + "a: 1\r\nc: 2\r\nc: two\r\ni: 5\r\nk: 6\r\nk: six\r\n"); if (!TryConstruct(lDEFGH, true, lBytes, out var lNotDEFGH)) { throw new cTestsException($"{nameof(cHeaderFields)}.2.4"); } lBytes = new cBytes( "Importance: error\r\n" + "a: 1\r\nc: 2\r\nc: two\r\ne: 3\r\n"); if (!TryConstruct(lGHIJK, true, lBytes, out var lNotGHIJK)) { throw new cTestsException($"{nameof(cHeaderFields)}.2.5"); } if (lNotABCDE.Contains("a") || lNotABCDE.Contains("e") || !lNotABCDE.Contains("f") || !lNotABCDE.Contains("g")) { throw new cTestsException($"{nameof(cHeaderFields)}.2.6"); } if (lNotABCDE.Contains(lABCDE) || lNotABCDE.Contains(lDEFGH) || !lNotABCDE.Contains(lGHIJK)) { throw new cTestsException($"{nameof(cHeaderFields)}.2.7"); } if (!lNotABCDE.ContainsNone(lABCDE) || lNotABCDE.ContainsNone(lDEFGH) || lNotABCDE.ContainsNone(lGHIJK)) { throw new cTestsException($"{nameof(cHeaderFields)}.2.8"); } if (lNotABCDE.Missing(lABCDE) != lABCDE || lNotABCDE.Missing(lDEFGH) != new cHeaderFieldNames("d", "E") || lNotABCDE.Missing(lGHIJK).Count != 0) { throw new cTestsException($"{nameof(cHeaderFields)}.2.9"); } bool lFailed; lFailed = false; try { lNotABCDE.FirstNamed("A"); } catch { lFailed = true; } if (!lFailed) { throw new cTestsException($"{nameof(cHeaderFields)}.2.10"); } if (lNotABCDE.FirstNamed(kHeaderFieldName.MessageId) == null || lNotABCDE.FirstNamed(kHeaderFieldName.InReplyTo) == null || lNotABCDE.Importance != eImportance.normal) { throw new cTestsException($"{nameof(cHeaderFields)}.2.11"); } if (lNotDEFGH.Importance != eImportance.high) { throw new cTestsException($"{nameof(cHeaderFields)}.2.12"); } if (lNotGHIJK.Importance != null) { throw new cTestsException($"{nameof(cHeaderFields)}.2.13"); } if (!ReferenceEquals((lFieldsABCDE + null), lFieldsABCDE)) { throw new cTestsException($"{nameof(cHeaderFields)}.2.14.1"); } if (!ReferenceEquals((null + lFieldsABCDE), lFieldsABCDE)) { throw new cTestsException($"{nameof(cHeaderFields)}.2.14.2"); } if (!ReferenceEquals((lFieldsABCDE + lFields), lFields)) { throw new cTestsException($"{nameof(cHeaderFields)}.2.14.3"); } if (!ReferenceEquals(lFields, (lFieldsABCDE + lFields))) { throw new cTestsException($"{nameof(cHeaderFields)}.2.14.4"); } if (!ReferenceEquals(lFieldsABCDE, (lFieldsABCDE + lFieldsABCDE2))) { throw new cTestsException($"{nameof(cHeaderFields)}.2.14.5"); } var lNotDE = lNotABCDE + lNotDEFGH; if (!lNotDE.ContainsNone(new cHeaderFieldNames("d", "E"))) { throw new cTestsException($"{nameof(cHeaderFields)}.2.15.1"); } if (!lNotDE.Contains(lGHIJK)) { throw new cTestsException($"{nameof(cHeaderFields)}.2.15.2"); } if (!lNotDE.Contains(new cHeaderFieldNames("a", "c", "f", "h"))) { throw new cTestsException($"{nameof(cHeaderFields)}.2.15.3"); } if (lNotDE.AllNamed("a").Count() != 1 || lNotDE.AllNamed("b").Count() != 0 || lNotDE.AllNamed("c").Count() != 2 || lNotDE.AllNamed("f").Count() != 0 || lNotDE.AllNamed("g").Count() != 2 || lNotDE.AllNamed("h").Count() != 0 || lNotDE.AllNamed("i").Count() != 1 || lNotDE.AllNamed("j").Count() != 0 || lNotDE.AllNamed("k").Count() != 2) { throw new cTestsException($"{nameof(cHeaderFields)}.2.15.4"); } var lAll = lNotABCDE + lNotGHIJK; if (!lAll.Contains(lABCDE) || !lAll.Contains(lDEFGH) || !lAll.Contains(lGHIJK)) { throw new cTestsException($"{nameof(cHeaderFields)}.2.16.1"); } if (lAll.AllNamed("a").Count() != 1 || lAll.AllNamed("b").Count() != 0 || lAll.AllNamed("c").Count() != 2 || lAll.AllNamed("d").Count() != 0 || lAll.AllNamed("e").Count() != 1 || lAll.AllNamed("f").Count() != 0 || lAll.AllNamed("g").Count() != 2 || lAll.AllNamed("h").Count() != 0 || lAll.AllNamed("i").Count() != 1 || lAll.AllNamed("j").Count() != 0 || lAll.AllNamed("k").Count() != 2) { throw new cTestsException($"{nameof(cHeaderFields)}.2.16.2"); } var lNotABC = lNotABCDE + lFieldsDEFGH; if (!lNotABC.ContainsNone(new cHeaderFieldNames("a", "B", "C"))) { throw new cTestsException($"{nameof(cHeaderFields)}.2.17.1"); } if (!lNotABC.Contains(new cHeaderFieldNames("d", "e", "f", "g", "h"))) { throw new cTestsException($"{nameof(cHeaderFields)}.2.17.2"); } if (lNotABC.AllNamed("d").Count() != 0 || lNotABC.AllNamed("e").Count() != 1 || lNotABC.AllNamed("f").Count() != 0 || lNotABC.AllNamed("g").Count() != 2 || lNotABC.AllNamed("h").Count() != 0 || lNotABC.AllNamed("i").Count() != 1 || lNotABC.AllNamed("j").Count() != 0 || lNotABC.AllNamed("k").Count() != 2) { throw new cTestsException($"{nameof(cHeaderFields)}.2.16.2"); } var lNotABCDE2 = lNotABCDE + lFieldsGHIJK; if (!lNotABCDE2.ContainsNone(lABCDE) || !lNotABCDE2.Contains(lGHIJK)) { throw new cTestsException($"{nameof(cHeaderFields)}.2.18.1"); } if (lNotABCDE2.AllNamed("f").Count() != 0 || lNotABCDE2.AllNamed("g").Count() != 2 || lNotABCDE2.AllNamed("h").Count() != 0 || lNotABCDE2.AllNamed("i").Count() != 1 || lNotABCDE2.AllNamed("j").Count() != 0 || lNotABCDE2.AllNamed("k").Count() != 2) { throw new cTestsException($"{nameof(cHeaderFields)}.2.18.2"); } var lNotFGH = lFieldsABCDE + lNotDEFGH; if (!lNotFGH.ContainsNone(new cHeaderFieldNames("F", "G", "H")) || !lNotFGH.Contains(lABCDE)) { throw new cTestsException($"{nameof(cHeaderFields)}.2.19.1"); } if (lNotFGH.AllNamed("a").Count() != 1 || lNotFGH.AllNamed("b").Count() != 0 || lNotFGH.AllNamed("c").Count() != 2 || lNotFGH.AllNamed("d").Count() != 0 || lNotFGH.AllNamed("e").Count() != 1 || lNotFGH.AllNamed("i").Count() != 1 || lNotFGH.AllNamed("j").Count() != 0 || lNotFGH.AllNamed("k").Count() != 2) { throw new cTestsException($"{nameof(cHeaderFields)}.2.19.2"); } var lNotGHIJK2 = lFieldsABCDE + lNotGHIJK; if (!lNotGHIJK2.ContainsNone(lGHIJK) || !lNotGHIJK2.Contains(lABCDE)) { throw new cTestsException($"{nameof(cHeaderFields)}.2.20.1"); } if (lNotGHIJK2.AllNamed("a").Count() != 1 || lNotGHIJK2.AllNamed("b").Count() != 0 || lNotGHIJK2.AllNamed("c").Count() != 2 || lNotGHIJK2.AllNamed("d").Count() != 0 || lNotGHIJK2.AllNamed("e").Count() != 1 || lNotGHIJK2.AllNamed("f").Count() != 0) { throw new cTestsException($"{nameof(cHeaderFields)}.2.20.2"); } var lAtoH = lFieldsABCDE + lFieldsDEFGH; if (!lAtoH.Contains(lABCDE) || !lAtoH.Contains(lDEFGH) || !lAtoH.ContainsNone(new cHeaderFieldNames("I", "J", "K"))) { throw new cTestsException($"{nameof(cHeaderFields)}.2.21.1"); } if (lAtoH.AllNamed("a").Count() != 1 || lAtoH.AllNamed("b").Count() != 0 || lAtoH.AllNamed("c").Count() != 2 || lAtoH.AllNamed("d").Count() != 0 || lAtoH.AllNamed("e").Count() != 1 || lAtoH.AllNamed("f").Count() != 0 || lAtoH.AllNamed("g").Count() != 2 || lAtoH.AllNamed("h").Count() != 0) { throw new cTestsException($"{nameof(cHeaderFields)}.2.21.2"); } lFailed = false; try { lAtoH.AllNamed("i"); } catch { lFailed = true; } if (!lFailed) { throw new cTestsException($"{nameof(cHeaderFields)}.2.21.3"); } var lNotF = lFieldsABCDE + lFieldsGHIJK; if (lNotF.Contains("F") || !lNotF.Contains(lABCDE) || !lNotF.Contains(lGHIJK) || lNotF.Contains(lDEFGH)) { throw new cTestsException($"{nameof(cHeaderFields)}.2.22.1"); } if (lNotF.AllNamed("a").Count() != 1 || lNotF.AllNamed("b").Count() != 0 || lNotF.AllNamed("c").Count() != 2 || lNotF.AllNamed("d").Count() != 0 || lNotF.AllNamed("e").Count() != 1 || lNotF.AllNamed("g").Count() != 1 || lNotF.AllNamed("h").Count() != 0 || lNotF.AllNamed("i").Count() != 1 || lNotF.AllNamed("j").Count() != 0 || lNotF.AllNamed("k").Count() != 2) { throw new cTestsException($"{nameof(cHeaderFields)}.2.22.2"); } }
private static bool ZTryConstruct(cHeaderFieldNames pNames, bool pNot, IList <byte> pBytes, out cHeaderFields rFields) { if (pBytes == null) { rFields = null; return(false); } cBytesCursor lCursor = new cBytesCursor(pBytes); List <cHeaderField> lFields = new List <cHeaderField>(); while (true) { if (!lCursor.GetRFC822FieldName(out var lName)) { break; } lCursor.SkipRFC822WSP(); if (!lCursor.SkipByte(cASCII.COLON)) { rFields = null; return(false); } if (!lCursor.GetRFC822FieldValue(out var lValue)) { rFields = null; return(false); } if (lName.Equals(kHeaderFieldName.References, StringComparison.InvariantCultureIgnoreCase)) { if (cHeaderFieldMsgIds.TryConstruct(lName, lValue, out var lReferences)) { lFields.Add(lReferences); } else { lFields.Add(new cHeaderField(lName, new cBytes(lValue))); } } else if (lName.Equals(kHeaderFieldName.Importance, StringComparison.InvariantCultureIgnoreCase)) { if (cHeaderFieldImportance.TryConstruct(lValue, out var lImportance)) { lFields.Add(lImportance); } else { lFields.Add(new cHeaderField(lName, new cBytes(lValue))); } } else { lFields.Add(new cHeaderField(lName, new cBytes(lValue))); } } if (!lCursor.Position.AtEnd && !lCursor.SkipBytes(cBytesCursor.CRLF)) { rFields = null; return(false); } rFields = new cHeaderFields(pNames, pNot, lFields); return(true); }
internal static bool TryConstruct(cHeaderFieldNames pNames, bool pNot, IList <byte> pBytes, out cHeaderFields rFields) => ZTryConstruct(pNames, pNot, pBytes, out rFields);
private cHeaderFields(cHeaderFieldNames pNames, bool pNot, IList <cHeaderField> pFields) : base(pFields) { mNames = pNames ?? throw new ArgumentNullException(nameof(pNames)); mNot = pNot; }