/// <summary> /// Ensures that the specified items are cached for the specified messages. /// </summary> /// <param name="pMessages"></param> /// <param name="pItems"></param> /// <param name="pConfiguration">Operation specific timeout, cancellation token and progress callbacks.</param> /// <returns>A list of messages where something went wrong and the cache was not populated.</returns> /// <remarks> /// <note type="note"><see cref="cMessageCacheItems"/> has implicit conversions from other types including <see cref="fMessageProperties"/>. This means that you can use values of those types as arguments to this method.</note> /// </remarks> public List <cMessage> Fetch(IEnumerable <cMessage> pMessages, cMessageCacheItems pItems, cCacheItemFetchConfiguration pConfiguration) { var lContext = mRootContext.NewMethodV(true, nameof(cIMAPClient), nameof(Fetch), 3); if (pMessages == null) { throw new ArgumentNullException(nameof(pMessages)); } if (pItems == null) { throw new ArgumentNullException(nameof(pItems)); } var lMessageHandles = cMessageHandleList.FromMessages(pMessages); if (lMessageHandles.All(h => h.Contains(pItems))) { return(new List <cMessage>()); } var lTask = ZFetchCacheItemsAsync(lMessageHandles, pItems, pConfiguration, lContext); mSynchroniser.Wait(lTask, lContext); return(new List <cMessage>(from m in pMessages where !m.MessageHandle.Contains(pItems) select m)); }
private async Task ZFetchCacheItemsAsync(cMessageHandleList pMessageHandles, cMessageCacheItems pItems, cCacheItemFetchConfiguration pConfiguration, cTrace.cContext pParentContext) { var lContext = pParentContext.NewMethod(nameof(cIMAPClient), nameof(ZFetchCacheItemsAsync), pMessageHandles, pItems); if (mDisposed) { throw new ObjectDisposedException(nameof(cIMAPClient)); } var lSession = mSession; if (lSession == null || lSession.ConnectionState != eConnectionState.selected) { throw new InvalidOperationException(kInvalidOperationExceptionMessage.NotSelected); } if (pMessageHandles == null) { throw new ArgumentNullException(nameof(pMessageHandles)); } if (pItems == null) { throw new ArgumentNullException(nameof(pItems)); } if (pMessageHandles.Count == 0) { return; } if (pItems.IsEmpty) { return; } if (pConfiguration == null) { using (var lToken = mCancellationManager.GetToken(lContext)) { var lMC = new cMethodControl(mTimeout, lToken.CancellationToken); var lProgress = new cProgress(); await lSession.FetchCacheItemsAsync(lMC, pMessageHandles, pItems, lProgress, lContext).ConfigureAwait(false); } } else { var lMC = new cMethodControl(pConfiguration.Timeout, pConfiguration.CancellationToken); var lProgress = new cProgress(mSynchroniser, pConfiguration.Increment); await lSession.FetchCacheItemsAsync(lMC, pMessageHandles, pItems, lProgress, lContext).ConfigureAwait(false); } }
internal cMessage Message(iMailboxHandle pMailboxHandle, cUID pUID, cMessageCacheItems pItems) { var lContext = mRootContext.NewMethod(nameof(cIMAPClient), nameof(Message)); var lTask = ZUIDFetchCacheItemsAsync(pMailboxHandle, cUIDList.FromUID(pUID), pItems, null, lContext); mSynchroniser.Wait(lTask, lContext); var lResult = lTask.Result; if (lResult.Count == 0) { return(null); } if (lResult.Count == 1) { return(lResult[0]); } throw new cInternalErrorException(lContext); }
/// <summary> /// Compares two messages using the comparision implied by the value of this instance. /// </summary> /// <param name="pX"></param> /// <param name="pY"></param> /// <returns></returns> /// <remarks> /// If the attributes required for the comparision are not in the message cache they will be fetched from the server. /// </remarks> public int Compare(cMessage pX, cMessage pY) { if (pX == null) { if (pY == null) { return(0); } return(-1); } if (pY == null) { return(1); } cMessageCacheItems lItems = Attributes(out _); pX.Fetch(lItems); pY.Fetch(lItems); return(Compare(pX.MessageHandle, pY.MessageHandle)); }
internal async Task <bool> FetchAsync(iMessageHandle pMessageHandle, cMessageCacheItems pItems) { var lContext = mRootContext.NewMethodV(true, nameof(cIMAPClient), nameof(FetchAsync), 1); if (pMessageHandle == null) { throw new ArgumentNullException(nameof(pMessageHandle)); } if (pItems == null) { throw new ArgumentNullException(nameof(pItems)); } if (pMessageHandle.Contains(pItems)) { return(true); } await ZFetchCacheItemsAsync(cMessageHandleList.FromMessageHandle(pMessageHandle), pItems, null, lContext).ConfigureAwait(false); return(pMessageHandle.Contains(pItems)); }
internal bool Fetch(iMessageHandle pMessageHandle, cMessageCacheItems pItems) { var lContext = mRootContext.NewMethodV(true, nameof(cIMAPClient), nameof(Fetch), 1); if (pMessageHandle == null) { throw new ArgumentNullException(nameof(pMessageHandle)); } if (pItems == null) { throw new ArgumentNullException(nameof(pItems)); } if (pMessageHandle.Contains(pItems)) { return(true); } var lTask = ZFetchCacheItemsAsync(cMessageHandleList.FromMessageHandle(pMessageHandle), pItems, null, lContext); mSynchroniser.Wait(lTask, lContext); return(pMessageHandle.Contains(pItems)); }
private async Task ZUIDFetchCacheItemsAsync(cMethodControl pMC, iMailboxHandle pMailboxHandle, uint pUIDValidity, cUIntList pUIDs, cMessageCacheItems pItems, cTrace.cContext pParentContext) { // note that this will fail if the UIDValidity has changed (this is different to the behaviour of standard fetch) // note that the caller should have checked that pAttributes contains some attributes to fetch var lContext = pParentContext.NewMethod(nameof(cSession), nameof(ZUIDFetchCacheItemsAsync), pMC, pMailboxHandle, pUIDValidity, pUIDs, pItems); if (mDisposed) { throw new ObjectDisposedException(nameof(cSession)); } if (_ConnectionState != eConnectionState.selected) { throw new InvalidOperationException(kInvalidOperationExceptionMessage.NotSelected); } if (pMailboxHandle == null) { throw new ArgumentNullException(nameof(pMailboxHandle)); } if (pUIDs == null) { throw new ArgumentNullException(nameof(pUIDs)); } if (pItems == null) { throw new ArgumentNullException(nameof(pItems)); } if (pUIDs.Count == 0) { throw new ArgumentOutOfRangeException(nameof(pUIDs)); } if (pItems.IsEmpty) { throw new ArgumentOutOfRangeException(nameof(pItems)); } using (var lBuilder = new cCommandDetailsBuilder()) { lBuilder.Add(await mSelectExclusiveAccess.GetBlockAsync(pMC, lContext).ConfigureAwait(false)); // block select cSelectedMailbox lSelectedMailbox = mMailboxCache.CheckIsSelectedMailbox(pMailboxHandle, pUIDValidity); lBuilder.Add(await mMSNUnsafeBlock.GetBlockAsync(pMC, lContext).ConfigureAwait(false)); // this command is msnunsafe lBuilder.AddUIDValidity(pUIDValidity); // the command is sensitive to UIDValidity changes lBuilder.Add(kFetchCommandPartUIDFetchSpace, new cTextCommandPart(cSequenceSet.FromUInts(pUIDs)), cCommandPart.Space); lBuilder.Add(pItems, lSelectedMailbox.MessageCache.NoModSeq); var lResult = await mPipeline.ExecuteAsync(pMC, lBuilder.EmitCommandDetails(), lContext).ConfigureAwait(false); if (lResult.ResultType == eCommandResultType.ok) { lContext.TraceInformation("uid fetch success"); return; } if (lResult.ResultType == eCommandResultType.no) { throw new cUnsuccessfulCompletionException(lResult.ResponseText, 0, lContext); } throw new cProtocolErrorException(lResult, 0, lContext); } }
public cFetchCacheItemsGroup(cMessageCacheItems pItems) { Items = pItems ?? throw new ArgumentNullException(nameof(pItems)); }
private IEnumerable <cFetchCacheItemsGroup> ZFetchCacheItemsGroups(cMessageHandleList pMessageHandles, cMessageCacheItems pItems) { Dictionary <cMessageCacheItems, cFetchCacheItemsGroup> lGroups = new Dictionary <cMessageCacheItems, cFetchCacheItemsGroup>(); foreach (var lMessageHandle in pMessageHandles) { cMessageCacheItems lItems; if (lMessageHandle.Expunged) { lItems = cMessageCacheItems.Empty; // none to get } else { lItems = lMessageHandle.Missing(pItems); // might also be none to get } cFetchCacheItemsGroup lGroup; if (!lGroups.TryGetValue(lItems, out lGroup)) { lGroup = new cFetchCacheItemsGroup(lItems); lGroups.Add(lItems, lGroup); } if (lMessageHandle.UID == null) { lGroup.MSNHandleCount++; } lGroup.MessageHandles.Add(lMessageHandle); } return(lGroups.Values); }
public async Task FetchCacheItemsAsync(cMethodControl pMC, cMessageHandleList pMessageHandles, cMessageCacheItems pItems, cProgress pProgress, cTrace.cContext pParentContext) { var lContext = pParentContext.NewMethod(nameof(cSession), nameof(FetchCacheItemsAsync), pMC, pMessageHandles, pItems); if (mDisposed) { throw new ObjectDisposedException(nameof(cSession)); } if (_ConnectionState != eConnectionState.selected) { throw new InvalidOperationException(kInvalidOperationExceptionMessage.NotSelected); } if (pMessageHandles == null) { throw new ArgumentNullException(nameof(pMessageHandles)); } if (pItems == null) { throw new ArgumentNullException(nameof(pItems)); } if (pProgress == null) { throw new ArgumentNullException(nameof(pProgress)); } mMailboxCache.CheckInSelectedMailbox(pMessageHandles); // to be repeated inside the select lock // split the handles into groups based on what attributes need to be retrieved, for each group do the retrieval foreach (var lGroup in ZFetchCacheItemsGroups(pMessageHandles, pItems)) { await ZFetchCacheItemsAsync(pMC, lGroup, pProgress, lContext).ConfigureAwait(false); } }
internal Task <List <cMessage> > MessagesAsync(iMailboxHandle pMailboxHandle, IEnumerable <cUID> pUIDs, cMessageCacheItems pItems, cCacheItemFetchConfiguration pConfiguration) { var lContext = mRootContext.NewMethod(nameof(cIMAPClient), nameof(MessagesAsync)); return(ZUIDFetchCacheItemsAsync(pMailboxHandle, cUIDList.FromUIDs(pUIDs), pItems, pConfiguration, lContext)); }
private async Task ZMessagesFetchAsync(cMethodControl pMC, cSession pSession, cMessageHandleList pMessageHandles, cMessageCacheItems pItems, cMessageFetchConfiguration pConfiguration, cTrace.cContext pParentContext) { var lContext = pParentContext.NewMethod(nameof(cIMAPClient), nameof(ZMessagesFetchAsync), pMC, pMessageHandles, pItems); if (pMessageHandles.Count == 0) { return; } if (pItems.IsEmpty) { return; } if (pMessageHandles.TrueForAll(h => h.Contains(pItems))) { return; } cProgress lProgress; if (pConfiguration == null) { lProgress = new cProgress(); } else { mSynchroniser.InvokeActionInt(pConfiguration.SetCount, pMessageHandles.Count, lContext); lProgress = new cProgress(mSynchroniser, pConfiguration.Increment); } await pSession.FetchCacheItemsAsync(pMC, pMessageHandles, pItems, lProgress, lContext).ConfigureAwait(false); }
internal async Task <cMessage> MessageAsync(iMailboxHandle pMailboxHandle, cUID pUID, cMessageCacheItems pItems) { var lContext = mRootContext.NewMethod(nameof(cIMAPClient), nameof(MessageAsync)); var lResult = await ZUIDFetchCacheItemsAsync(pMailboxHandle, cUIDList.FromUID(pUID), pItems, null, lContext).ConfigureAwait(false); if (lResult.Count == 0) { return(null); } if (lResult.Count == 1) { return(lResult[0]); } throw new cInternalErrorException(lContext); }
public async Task <cMessageHandleList> UIDFetchCacheItemsAsync(cMethodControl pMC, iMailboxHandle pMailboxHandle, cUIDList pUIDs, cMessageCacheItems pItems, cProgress pProgress, cTrace.cContext pParentContext) { var lContext = pParentContext.NewMethod(nameof(cSession), nameof(UIDFetchCacheItemsAsync), pMC, pMailboxHandle, pUIDs, pItems); if (mDisposed) { throw new ObjectDisposedException(nameof(cSession)); } if (_ConnectionState != eConnectionState.selected) { throw new InvalidOperationException(kInvalidOperationExceptionMessage.NotSelected); } if (pMailboxHandle == null) { throw new ArgumentNullException(nameof(pMailboxHandle)); } if (pUIDs == null) { throw new ArgumentNullException(nameof(pUIDs)); } if (pItems == null) { throw new ArgumentNullException(nameof(pItems)); } if (pProgress == null) { throw new ArgumentNullException(nameof(pProgress)); } if (pUIDs.Count == 0) { throw new ArgumentOutOfRangeException(nameof(pUIDs)); } if (pItems.IsEmpty) { throw new ArgumentOutOfRangeException(nameof(pItems)); } uint lUIDValidity = pUIDs[0].UIDValidity; mMailboxCache.CheckIsSelectedMailbox(pMailboxHandle, lUIDValidity); // to be repeated inside the select lock // split the list into those messages I have handles for and those I dont ///////////////////////////////////////////////////////////////////////// cMessageHandleList lMessageHandles = new cMessageHandleList(); cUIDList lUIDs = new cUIDList(); // check the selected mailbox and resolve uids -> handles whilst blocking select exclusive access // using (var lBlock = await mSelectExclusiveAccess.GetBlockAsync(pMC, lContext).ConfigureAwait(false)) { cSelectedMailbox lSelectedMailbox = mMailboxCache.CheckIsSelectedMailbox(pMailboxHandle, lUIDValidity); foreach (var lUID in pUIDs) { var lMessageHandle = lSelectedMailbox.GetHandle(lUID); if (lMessageHandle == null) { lUIDs.Add(lUID); // don't have a handle } else if (lMessageHandle.ContainsNone(pItems)) { lUIDs.Add(lUID); // have to get all the attributes, may as well fetch them with the ones where I might need all the attributes } else { lMessageHandles.Add(lMessageHandle); } } } // for the messages I have handles for, fetch the missing attributes //////////////////////////////////////////////////////////////////// if (lMessageHandles.Count > 0) { // split the handles into groups based on what attributes need to be retrieved, for each group do the retrieval foreach (var lGroup in ZFetchCacheItemsGroups(lMessageHandles, pItems)) { await ZFetchCacheItemsAsync(pMC, lGroup, pProgress, lContext).ConfigureAwait(false); } } // for the messages only identified by UID or where I have to get all the items //////////////////////////////////////////////////////////////////////////////////// if (lUIDs.Count > 0) { await ZUIDFetchCacheItemsAsync(pMC, pMailboxHandle, lUIDs, pItems, pProgress, lContext).ConfigureAwait(false); // resolve uids -> handles whilst blocking select exclusive access // using (var lBlock = await mSelectExclusiveAccess.GetBlockAsync(pMC, lContext).ConfigureAwait(false)) { cSelectedMailbox lSelectedMailbox = mMailboxCache.CheckIsSelectedMailbox(pMailboxHandle, lUIDValidity); foreach (var lUID in lUIDs) { var lMessageHandle = lSelectedMailbox.GetHandle(lUID); if (lMessageHandle != null) { lMessageHandles.Add(lMessageHandle); } } } } return(lMessageHandles); }
private async Task ZUIDFetchCacheItemsAsync(cMethodControl pMC, iMailboxHandle pMailboxHandle, cUIDList pUIDs, cMessageCacheItems pItems, cProgress pProgress, cTrace.cContext pParentContext) { var lContext = pParentContext.NewMethod(nameof(cSession), nameof(ZUIDFetchCacheItemsAsync), pMC, pMailboxHandle, pUIDs, pItems); // get the UIDValidity uint lUIDValidity = pUIDs[0].UIDValidity; // sort the uids so we might get good sequence sets pUIDs.Sort(); int lIndex = 0; Stopwatch lStopwatch = new Stopwatch(); while (lIndex < pUIDs.Count) { // the number of messages to fetch this time int lFetchCount = mFetchCacheItemsSizer.Current; // get the UIDs to fetch this time cUIntList lUIDs = new cUIntList(); while (lIndex < pUIDs.Count && lUIDs.Count < lFetchCount) { lUIDs.Add(pUIDs[lIndex++].UID); } // fetch lStopwatch.Restart(); await ZUIDFetchCacheItemsAsync(pMC, pMailboxHandle, lUIDValidity, lUIDs, pItems, lContext).ConfigureAwait(false); lStopwatch.Stop(); // store the time taken so the next fetch is a better size mFetchCacheItemsSizer.AddSample(lUIDs.Count, lStopwatch.ElapsedMilliseconds); // update progress pProgress.Increment(lUIDs.Count, lContext); } }
private async Task <List <cMessage> > ZZMessagesAsync(cMethodControl pMC, iMailboxHandle pMailboxHandle, cFilter pFilter, cSort pSort, cMessageCacheItems pItems, cMessageFetchConfiguration pConfiguration, cTrace.cContext pParentContext) { var lContext = pParentContext.NewMethod(nameof(cIMAPClient), nameof(ZZMessagesAsync), pMC, pMailboxHandle, pFilter, pSort, pItems); if (mDisposed) { throw new ObjectDisposedException(nameof(cIMAPClient)); } var lSession = mSession; if (lSession == null || lSession.ConnectionState != eConnectionState.selected) { throw new InvalidOperationException(kInvalidOperationExceptionMessage.NotSelected); } if (pMailboxHandle == null) { throw new ArgumentNullException(nameof(pMailboxHandle)); } if (pFilter == null) { throw new ArgumentNullException(nameof(pFilter)); } if (pSort == null) { throw new ArgumentNullException(nameof(pSort)); } if (pItems == null) { throw new ArgumentNullException(nameof(pItems)); } cMessageCacheItems lItems; if (ReferenceEquals(pSort, cSort.None)) { lItems = pItems; } /* de-implemented pending a requirement to complete it * else if (ReferenceEquals(pSort, cSort.ThreadOrderedSubject)) * { * if (lSession.Capabilities.ThreadOrderedSubject) return await ZMessagesThreadAsync(pMC, lSession, pHandle, eMessageThreadAlgorithm.orderedsubject, pFilter, pItems, pConfiguration, lContext).ConfigureAwait(false); * lItems = new cCacheItems(pItems.Attributes | fCacheAttributes.envelope | fCacheAttributes.received, pItems.Names); * } * else if (ReferenceEquals(pSort, cSort.ThreadReferences)) * { * if (lSession.Capabilities.ThreadReferences) return await ZMessagesThreadAsync(pMC, lSession, pHandle, eMessageThreadAlgorithm.references, pFilter, pItems, pConfiguration, lContext).ConfigureAwait(false); * lItems = new cCacheItems(pItems.Attributes | fCacheAttributes.envelope | fCacheAttributes.received, pItems.Names.Union(cHeaderFieldNames.References)); * } */ else { var lSortAttributes = pSort.Attributes(out var lSortDisplay); if (!lSortDisplay && lSession.Capabilities.Sort || lSortDisplay && lSession.Capabilities.SortDisplay) { return(await ZMessagesSortAsync(pMC, lSession, pMailboxHandle, pSort, pFilter, pItems, pConfiguration, lContext).ConfigureAwait(false)); } lItems = new cMessageCacheItems(pItems.Attributes | lSortAttributes, pItems.Names); } cMessageHandleList lMessageHandles; if (lSession.Capabilities.ESearch) { lMessageHandles = await lSession.SearchExtendedAsync(pMC, pMailboxHandle, pFilter, lContext).ConfigureAwait(false); } else { lMessageHandles = await lSession.SearchAsync(pMC, pMailboxHandle, pFilter, lContext).ConfigureAwait(false); } // get the properties await ZMessagesFetchAsync(pMC, lSession, lMessageHandles, lItems, pConfiguration, lContext).ConfigureAwait(false); if (ReferenceEquals(pSort, cSort.None)) { return(ZMessagesFlatMessageList(lMessageHandles, lContext)); } // client side sorting // de-implemented pending a requirement to complete it // if (ReferenceEquals(pSort, cSort.ThreadOrderedSubject)) return ZMessagesThreadOrderedSubject(lHandles, lContext); // if (ReferenceEquals(pSort, cSort.ThreadReferences)) return ZMessagesThreadReferences(lHandles, lContext); lMessageHandles.Sort(pSort); return(ZMessagesFlatMessageList(lMessageHandles, lContext)); }
private async Task <List <cMessage> > ZMessagesAsync(iMailboxHandle pMailboxHandle, cFilter pFilter, cSort pSort, cMessageCacheItems pItems, cMessageFetchConfiguration pConfiguration, cTrace.cContext pParentContext) { var lContext = pParentContext.NewMethod(nameof(cIMAPClient), nameof(ZMessagesAsync), pMailboxHandle, pFilter, pSort, pItems); if (pConfiguration == null) { using (var lToken = mCancellationManager.GetToken(lContext)) { var lMC = new cMethodControl(mTimeout, lToken.CancellationToken); return(await ZZMessagesAsync(lMC, pMailboxHandle, pFilter, pSort, pItems, null, lContext).ConfigureAwait(false)); } } else { var lMC = new cMethodControl(pConfiguration.Timeout, pConfiguration.CancellationToken); return(await ZZMessagesAsync(lMC, pMailboxHandle, pFilter, pSort, pItems, pConfiguration, lContext).ConfigureAwait(false)); } }
internal Task <List <cMessage> > MessagesAsync(iMailboxHandle pMailboxHandle, cFilter pFilter, cSort pSort, cMessageCacheItems pItems, cMessageFetchConfiguration pConfiguration) { var lContext = mRootContext.NewMethod(nameof(cIMAPClient), nameof(MessagesAsync)); return(ZMessagesAsync(pMailboxHandle, pFilter, pSort, pItems, pConfiguration, lContext)); }
internal List <cMessage> Messages(iMailboxHandle pMailboxHandle, cFilter pFilter, cSort pSort, cMessageCacheItems pItems, cMessageFetchConfiguration pConfiguration) { var lContext = mRootContext.NewMethod(nameof(cIMAPClient), nameof(Messages)); var lTask = ZMessagesAsync(pMailboxHandle, pFilter, pSort, pItems, pConfiguration, lContext); mSynchroniser.Wait(lTask, lContext); return(lTask.Result); }
private async Task <List <cMessage> > ZMessagesSortAsync(cMethodControl pMC, cSession pSession, iMailboxHandle pMailboxHandle, cSort pSort, cFilter pFilter, cMessageCacheItems pItems, cMessageFetchConfiguration pConfiguration, cTrace.cContext pParentContext) { var lContext = pParentContext.NewMethod(nameof(cIMAPClient), nameof(ZMessagesSortAsync), pMC, pMailboxHandle, pSort, pFilter, pItems); cMessageHandleList lMessageHandles; if (pSession.Capabilities.ESort) { lMessageHandles = await pSession.SortExtendedAsync(pMC, pMailboxHandle, pFilter, pSort, lContext).ConfigureAwait(false); } else { lMessageHandles = await pSession.SortAsync(pMC, pMailboxHandle, pFilter, pSort, lContext).ConfigureAwait(false); } await ZMessagesFetchAsync(pMC, pSession, lMessageHandles, pItems, pConfiguration, lContext).ConfigureAwait(false); return(ZMessagesFlatMessageList(lMessageHandles, lContext)); }
internal async Task <cMessageHandleList> FetchAsync(IEnumerable <iMessageHandle> pMessageHandles, cMessageCacheItems pItems, cCacheItemFetchConfiguration pConfiguration) { var lContext = mRootContext.NewMethodV(true, nameof(cIMAPClient), nameof(FetchAsync), 2); if (pMessageHandles == null) { throw new ArgumentNullException(nameof(pMessageHandles)); } if (pItems == null) { throw new ArgumentNullException(nameof(pItems)); } var lMessageHandles = cMessageHandleList.FromMessageHandles(pMessageHandles); if (lMessageHandles.All(h => h.Contains(pItems))) { return(new cMessageHandleList()); } await ZFetchCacheItemsAsync(lMessageHandles, pItems, pConfiguration, lContext).ConfigureAwait(false); return(new cMessageHandleList(from h in lMessageHandles where !h.Contains(pItems) select h)); }
public cMessageCacheItems Missing(cMessageCacheItems pItems) => new cMessageCacheItems(~mAttributes & pItems.Attributes, HeaderFields.Missing(pItems.Names));
private async Task <List <cMessage> > ZUIDFetchCacheItemsAsync(iMailboxHandle pMailboxHandle, cUIDList pUIDs, cMessageCacheItems pItems, cCacheItemFetchConfiguration pConfiguration, cTrace.cContext pParentContext) { var lContext = pParentContext.NewMethod(nameof(cIMAPClient), nameof(ZUIDFetchCacheItemsAsync), pMailboxHandle, pUIDs, pItems); if (mDisposed) { throw new ObjectDisposedException(nameof(cIMAPClient)); } var lSession = mSession; if (lSession == null || lSession.ConnectionState != eConnectionState.selected) { throw new InvalidOperationException(kInvalidOperationExceptionMessage.NotSelected); } if (pMailboxHandle == null) { throw new ArgumentNullException(nameof(pMailboxHandle)); } if (pUIDs == null) { throw new ArgumentNullException(nameof(pUIDs)); } if (pItems == null) { throw new ArgumentNullException(nameof(pItems)); } if (pUIDs.Count == 0) { return(new List <cMessage>()); } if (pItems.IsEmpty) { throw new ArgumentOutOfRangeException(nameof(pItems)); } cMessageHandleList lMessageHandles; if (pConfiguration == null) { using (var lToken = mCancellationManager.GetToken(lContext)) { var lMC = new cMethodControl(mTimeout, lToken.CancellationToken); var lProgress = new cProgress(); lMessageHandles = await lSession.UIDFetchCacheItemsAsync(lMC, pMailboxHandle, pUIDs, pItems, lProgress, lContext).ConfigureAwait(false); } } else { var lMC = new cMethodControl(pConfiguration.Timeout, pConfiguration.CancellationToken); var lProgress = new cProgress(mSynchroniser, pConfiguration.Increment); lMessageHandles = await lSession.UIDFetchCacheItemsAsync(lMC, pMailboxHandle, pUIDs, pItems, lProgress, lContext).ConfigureAwait(false); } List <cMessage> lMessages = new List <cMessage>(lMessageHandles.Count); foreach (var lMessageHandle in lMessageHandles) { lMessages.Add(new cMessage(this, lMessageHandle)); } return(lMessages); }
internal List <cMessage> Messages(iMailboxHandle pMailboxHandle, IEnumerable <cUID> pUIDs, cMessageCacheItems pItems, cCacheItemFetchConfiguration pConfiguration) { var lContext = mRootContext.NewMethod(nameof(cIMAPClient), nameof(Messages)); var lTask = ZUIDFetchCacheItemsAsync(pMailboxHandle, cUIDList.FromUIDs(pUIDs), pItems, pConfiguration, lContext); mSynchroniser.Wait(lTask, lContext); return(lTask.Result); }
private async Task ZFetchCacheItemsAsync(cMethodControl pMC, cMessageHandleList pMessageHandles, cMessageCacheItems pItems, cTrace.cContext pParentContext) { var lContext = pParentContext.NewMethod(nameof(cSession), nameof(ZFetchCacheItemsAsync), pMC, pMessageHandles, pItems); if (mDisposed) { throw new ObjectDisposedException(nameof(cSession)); } if (_ConnectionState != eConnectionState.selected) { throw new InvalidOperationException(kInvalidOperationExceptionMessage.NotSelected); } if (pMessageHandles == null) { throw new ArgumentNullException(nameof(pMessageHandles)); } if (pItems == null) { throw new ArgumentNullException(nameof(pItems)); } if (pMessageHandles.Count == 0) { throw new ArgumentOutOfRangeException(nameof(pMessageHandles)); } if (pItems.IsEmpty) { throw new ArgumentOutOfRangeException(nameof(pItems)); } using (var lBuilder = new cCommandDetailsBuilder()) { lBuilder.Add(await mSelectExclusiveAccess.GetBlockAsync(pMC, lContext).ConfigureAwait(false)); // block select cSelectedMailbox lSelectedMailbox = mMailboxCache.CheckInSelectedMailbox(pMessageHandles); lBuilder.Add(await mPipeline.GetIdleBlockTokenAsync(pMC, lContext).ConfigureAwait(false)); // stop the pipeline from iding (idle is msnunsafe) lBuilder.Add(await mMSNUnsafeBlock.GetTokenAsync(pMC, lContext).ConfigureAwait(false)); // wait until all commands that are msnunsafe complete, block all commands that are msnunsafe // uidvalidity must be captured before the handles are resolved lBuilder.AddUIDValidity(lSelectedMailbox.MessageCache.UIDValidity); // resolve MSNs cUIntList lMSNs = new cUIntList(); foreach (var lMessageHandle in pMessageHandles) { var lMSN = lSelectedMailbox.GetMSN(lMessageHandle); if (lMSN != 0) { lMSNs.Add(lMSN); } } if (lMSNs.Count == 0) { return; } // build command lBuilder.Add(kFetchCommandPartFetchSpace, new cTextCommandPart(cSequenceSet.FromUInts(lMSNs)), cCommandPart.Space); lBuilder.Add(pItems, lSelectedMailbox.MessageCache.NoModSeq); // go var lResult = await mPipeline.ExecuteAsync(pMC, lBuilder.EmitCommandDetails(), lContext).ConfigureAwait(false); if (lResult.ResultType == eCommandResultType.ok) { lContext.TraceInformation("fetch success"); return; } if (lResult.ResultType == eCommandResultType.no) { throw new cUnsuccessfulCompletionException(lResult.ResponseText, 0, lContext); } throw new cProtocolErrorException(lResult, 0, lContext); } }
public bool ContainsNone(cMessageCacheItems pItems) => (~mAttributes & pItems.Attributes) == pItems.Attributes && HeaderFields.ContainsNone(pItems.Names);