public void Unselect(cTrace.cContext pParentContext) { var lContext = pParentContext.NewMethod(nameof(cMailboxCache), nameof(Unselect)); if (mSelectedMailbox == null) { return; } var lMailboxHandle = mSelectedMailbox.MailboxHandle; fMailboxProperties lProperties = fMailboxProperties.isselected; if (mSelectedMailbox.SelectedForUpdate) { lProperties |= fMailboxProperties.isselectedforupdate; } if (mSelectedMailbox.AccessReadOnly) { lProperties |= fMailboxProperties.isaccessreadonly; } mSelectedMailbox = null; mSetState(eConnectionState.notselected, lContext); mSynchroniser.InvokeMailboxPropertiesChanged(lMailboxHandle, lProperties, lContext); mSynchroniser.InvokePropertyChanged(nameof(cIMAPClient.SelectedMailbox), lContext); }
private async Task ZUIDStoreAsync(cMethodControl pMC, iMailboxHandle pMailboxHandle, uint pUIDValidity, cStoreFeedbackCollector pFeedbackCollector, eStoreOperation pOperation, cStorableFlags pFlags, ulong?pIfUnchangedSinceModSeq, cUIDStoreFeedback pFeedback, cTrace.cContext pParentContext) { var lContext = pParentContext.NewMethod(nameof(cSession), nameof(ZStoreAsync), pMC, pMailboxHandle, pUIDValidity, pFeedbackCollector, pOperation, pFlags, pIfUnchangedSinceModSeq, pFeedback); // no validation ... all the parameters have been validated already by the cSession by the time we get here using (var lBuilder = new cCommandDetailsBuilder()) { lBuilder.Add(await mSelectExclusiveAccess.GetBlockAsync(pMC, lContext).ConfigureAwait(false)); // block select cSelectedMailbox lSelectedMailbox = mMailboxCache.CheckIsSelectedMailbox(pMailboxHandle, pUIDValidity); if (!lSelectedMailbox.SelectedForUpdate) { throw new InvalidOperationException(kInvalidOperationExceptionMessage.NotSelectedForUpdate); } lBuilder.Add(await mMSNUnsafeBlock.GetBlockAsync(pMC, lContext).ConfigureAwait(false)); // this command is msnunsafe lBuilder.AddUIDValidity(pUIDValidity); // the command is sensitive to UIDValidity changes // build the command lBuilder.Add(kUIDStoreCommandPartUIDStoreSpace, new cTextCommandPart(cSequenceSet.FromUInts(pFeedbackCollector.UInts)), cCommandPart.Space); if (pIfUnchangedSinceModSeq != null) { lBuilder.Add(kStoreCommandPartLParenUnchangedSinceSpace, new cTextCommandPart(pIfUnchangedSinceModSeq.Value), kStoreCommandPartRParenSpace); } lBuilder.Add(pOperation, pFlags); // add the hook var lHook = new cCommandHookStore(pFeedbackCollector, pFeedback, lSelectedMailbox); lBuilder.Add(lHook); // submit the command var lResult = await mPipeline.ExecuteAsync(pMC, lBuilder.EmitCommandDetails(), lContext).ConfigureAwait(false); // note: the base spec states that non-existent UIDs are ignored without comment => a NO from a UID STORE is unexpected if (lResult.ResultType == eCommandResultType.ok) { lContext.TraceInformation("uid store success"); return; } fCapabilities lTryIgnoring; if (pIfUnchangedSinceModSeq == null) { lTryIgnoring = 0; } else { lTryIgnoring = fCapabilities.condstore; } if (lResult.ResultType == eCommandResultType.no) { throw new cUnsuccessfulCompletionException(lResult.ResponseText, lTryIgnoring, lContext); } throw new cProtocolErrorException(lResult, lTryIgnoring, lContext); } }
public async Task UIDStoreAsync(cMethodControl pMC, iMailboxHandle pMailboxHandle, cUIDStoreFeedback pFeedback, eStoreOperation pOperation, cStorableFlags pFlags, ulong?pIfUnchangedSinceModSeq, cTrace.cContext pParentContext) { var lContext = pParentContext.NewMethod(nameof(cSession), nameof(UIDStoreAsync), pMC, pMailboxHandle, pFeedback, pOperation, pFlags, pIfUnchangedSinceModSeq); 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 (pFeedback == null) { throw new ArgumentNullException(nameof(pFeedback)); } if (pFlags == null) { throw new ArgumentNullException(nameof(pFlags)); } if (pFeedback.Count == 0) { throw new ArgumentOutOfRangeException(nameof(pFeedback)); } if (pIfUnchangedSinceModSeq == 0) { throw new ArgumentOutOfRangeException(nameof(pIfUnchangedSinceModSeq)); } if (pIfUnchangedSinceModSeq != null && !_Capabilities.CondStore) { throw new InvalidOperationException(kInvalidOperationExceptionMessage.CondStoreNotInUse); } uint lUIDValidity = pFeedback[0].UID.UIDValidity; cSelectedMailbox lSelectedMailbox = mMailboxCache.CheckIsSelectedMailbox(pMailboxHandle, lUIDValidity); // to be repeated inside the select lock if (!lSelectedMailbox.SelectedForUpdate) { throw new InvalidOperationException(kInvalidOperationExceptionMessage.NotSelectedForUpdate); // to be repeated inside the select lock } cStoreFeedbackCollector lFeedbackCollector = new cStoreFeedbackCollector(pFeedback); await ZUIDStoreAsync(pMC, pMailboxHandle, lUIDValidity, lFeedbackCollector, pOperation, pFlags, pIfUnchangedSinceModSeq, pFeedback, lContext).ConfigureAwait(false); }
public void Select(iMailboxHandle pMailboxHandle, bool pForUpdate, bool pAccessReadOnly, bool pUIDNotSticky, cFetchableFlags pFlags, cPermanentFlags pPermanentFlags, int pExists, int pRecent, uint pUIDNext, uint pUIDValidity, uint pHighestModSeq, cTrace.cContext pParentContext) { var lContext = pParentContext.NewMethod(nameof(cMailboxCache), nameof(Select), pMailboxHandle, pForUpdate, pAccessReadOnly, pUIDNotSticky, pFlags, pPermanentFlags, pExists, pRecent, pUIDNext, pUIDValidity, pHighestModSeq); if (mSelectedMailbox != null) { throw new InvalidOperationException(); } if (pMailboxHandle == null) { throw new ArgumentNullException(nameof(pMailboxHandle)); } if (pFlags == null) { throw new ArgumentNullException(nameof(pFlags)); } var lItem = CheckHandle(pMailboxHandle); if (pExists < 0) { throw new ArgumentOutOfRangeException(nameof(pExists)); } if (pRecent < 0) { throw new ArgumentOutOfRangeException(nameof(pRecent)); } mSelectedMailbox = new cSelectedMailbox(mSynchroniser, lItem, pForUpdate, pAccessReadOnly, pExists, pRecent, pUIDNext, pUIDValidity, pHighestModSeq, lContext); lItem.SetSelectedProperties(pUIDNotSticky, pFlags, pForUpdate, pPermanentFlags, lContext); fMailboxProperties lProperties = fMailboxProperties.isselected; if (pForUpdate) { lProperties |= fMailboxProperties.isselectedforupdate; } if (pAccessReadOnly) { lProperties |= fMailboxProperties.isaccessreadonly; } mSetState(eConnectionState.selected, lContext); mSynchroniser.InvokeMailboxPropertiesChanged(pMailboxHandle, lProperties, lContext); mSynchroniser.InvokePropertyChanged(nameof(cIMAPClient.SelectedMailbox), lContext); }
public Task <cCopyFeedback> CopyAsync(cMethodControl pMC, cMessageHandleList pSourceMessageHandles, iMailboxHandle pDestinationMailboxHandle, cTrace.cContext pParentContext) { var lContext = pParentContext.NewMethod(nameof(cSession), nameof(CopyAsync), pMC, pSourceMessageHandles, pDestinationMailboxHandle); if (mDisposed) { throw new ObjectDisposedException(nameof(cSession)); } if (_ConnectionState != eConnectionState.selected) { throw new InvalidOperationException(kInvalidOperationExceptionMessage.NotSelected); } if (pSourceMessageHandles == null) { throw new ArgumentNullException(nameof(pSourceMessageHandles)); } if (pDestinationMailboxHandle == null) { throw new ArgumentNullException(nameof(pDestinationMailboxHandle)); } if (pSourceMessageHandles.Count == 0) { throw new ArgumentOutOfRangeException(nameof(pSourceMessageHandles)); } cSelectedMailbox lSelectedMailbox = mMailboxCache.CheckInSelectedMailbox(pSourceMessageHandles); // to be repeated inside the select lock var lDestinationItem = mMailboxCache.CheckHandle(pDestinationMailboxHandle); if (pSourceMessageHandles.TrueForAll(h => h.UID != null)) { var lMessageHandle = pSourceMessageHandles.Find(h => h.Expunged); if (lMessageHandle != null) { throw new cMessageExpungedException(lMessageHandle); } return(ZUIDCopyAsync(pMC, lSelectedMailbox.MailboxHandle, pSourceMessageHandles[0].UID.UIDValidity, new cUIntList(from h in pSourceMessageHandles select h.UID.UID), lDestinationItem, lContext)); } else { return(ZCopyAsync(pMC, pSourceMessageHandles, lDestinationItem, lContext)); } }
public Task <cCopyFeedback> UIDCopyAsync(cMethodControl pMC, iMailboxHandle pSourceMailboxHandle, cUIDList pSourceUIDs, iMailboxHandle pDestinationMailboxHandle, cTrace.cContext pParentContext) { var lContext = pParentContext.NewMethod(nameof(cSession), nameof(UIDCopyAsync), pMC, pSourceMailboxHandle, pSourceUIDs, pDestinationMailboxHandle); if (mDisposed) { throw new ObjectDisposedException(nameof(cSession)); } if (_ConnectionState != eConnectionState.selected) { throw new InvalidOperationException(kInvalidOperationExceptionMessage.NotSelected); } if (pSourceMailboxHandle == null) { throw new ArgumentNullException(nameof(pSourceMailboxHandle)); } if (pSourceUIDs == null) { throw new ArgumentNullException(nameof(pSourceUIDs)); } if (pDestinationMailboxHandle == null) { throw new ArgumentNullException(nameof(pDestinationMailboxHandle)); } if (pSourceUIDs.Count == 0) { throw new ArgumentOutOfRangeException(nameof(pSourceUIDs)); } uint lSourceUIDValidity = pSourceUIDs[0].UIDValidity; cSelectedMailbox lSelectedMailbox = mMailboxCache.CheckIsSelectedMailbox(pSourceMailboxHandle, lSourceUIDValidity); // to be repeated inside the select lock var lDestinationItem = mMailboxCache.CheckHandle(pDestinationMailboxHandle); return(ZUIDCopyAsync(pMC, pSourceMailboxHandle, lSourceUIDValidity, new cUIntList(from lUID in pSourceUIDs select lUID.UID), lDestinationItem, lContext)); }
private async Task <cCopyFeedback> ZUIDCopyAsync(cMethodControl pMC, iMailboxHandle pSourceMailboxHandle, uint pSourceUIDValidity, cUIntList pSourceUIDs, cMailboxCacheItem pDestinationItem, cTrace.cContext pParentContext) { var lContext = pParentContext.NewMethod(nameof(cSession), nameof(ZCopyAsync), pMC, pSourceMailboxHandle, pSourceUIDValidity, pSourceUIDs, pDestinationItem); using (var lBuilder = new cCommandDetailsBuilder()) { lBuilder.Add(await mSelectExclusiveAccess.GetBlockAsync(pMC, lContext).ConfigureAwait(false)); // block select cSelectedMailbox lSelectedMailbox = mMailboxCache.CheckIsSelectedMailbox(pSourceMailboxHandle, pSourceUIDValidity); lBuilder.Add(await mMSNUnsafeBlock.GetBlockAsync(pMC, lContext).ConfigureAwait(false)); // this command is msnunsafe lBuilder.AddUIDValidity(pSourceUIDValidity); // the command is sensitive to UIDValidity changes // build the command lBuilder.Add(kUIDCopyCommandPart, new cTextCommandPart(cSequenceSet.FromUInts(pSourceUIDs)), cCommandPart.Space, pDestinationItem.MailboxNameCommandPart); // add the hook var lHook = new cCommandHookCopy(pSourceUIDValidity); lBuilder.Add(lHook); // submit the command var lResult = await mPipeline.ExecuteAsync(pMC, lBuilder.EmitCommandDetails(), lContext).ConfigureAwait(false); if (lResult.ResultType == eCommandResultType.ok) { lContext.TraceInformation("uid copy success"); return(lHook.Feedback); } if (lResult.ResultType == eCommandResultType.no) { throw new cUnsuccessfulCompletionException(lResult.ResponseText, 0, lContext); } throw new cProtocolErrorException(lResult, 0, lContext); } }
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 cCommandHookBaseSearch(cSelectedMailbox pSelectedMailbox) { mSelectedMailbox = pSelectedMailbox ?? throw new ArgumentNullException(nameof(pSelectedMailbox)); }
private async Task <cBody> ZFetchBodyAsync(cMethodControl pMC, iMessageHandle pMessageHandle, bool pBinary, cSection pSection, uint pOrigin, uint pLength, cTrace.cContext pParentContext) { // the caller must have checked that the binary option is compatible with the section (e.g. if binary is true the section can't specify a textpart) // the length must be greater than zero var lContext = pParentContext.NewMethod(nameof(cSession), nameof(ZFetchBodyAsync), pMC, pMessageHandle, pBinary, pSection, pOrigin, pLength); if (mDisposed) { throw new ObjectDisposedException(nameof(cSession)); } if (_ConnectionState != eConnectionState.selected) { throw new InvalidOperationException(kInvalidOperationExceptionMessage.NotSelected); } if (pMessageHandle == null) { throw new ArgumentNullException(nameof(pMessageHandle)); } if (pSection == null) { throw new ArgumentNullException(nameof(pSection)); } using (var lBuilder = new cCommandDetailsBuilder()) { lBuilder.Add(await mSelectExclusiveAccess.GetBlockAsync(pMC, lContext).ConfigureAwait(false)); // block select cSelectedMailbox lSelectedMailbox = mMailboxCache.CheckInSelectedMailbox(pMessageHandle); 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 set before the handle is resolved lBuilder.AddUIDValidity(lSelectedMailbox.MessageCache.UIDValidity); // resolve the MSN uint lMSN = lSelectedMailbox.GetMSN(pMessageHandle); if (lMSN == 0) { if (pMessageHandle.Expunged) { throw new cMessageExpungedException(pMessageHandle); } throw new ArgumentOutOfRangeException(nameof(pMessageHandle)); } // build command lBuilder.Add(kFetchCommandPartFetchSpace, new cTextCommandPart(lMSN)); if (pBinary) { lBuilder.Add(kFetchCommandPartSpaceBinaryPeekLBracket); } else { lBuilder.Add(kFetchCommandPartSpaceBodyPeekLBracket); } lBuilder.Add(pSection, pOrigin, pLength); // hook var lHook = new cCommandHookFetchBodyMSN(pBinary, pSection, pOrigin, lMSN); lBuilder.Add(lHook); // go var lResult = await mPipeline.ExecuteAsync(pMC, lBuilder.EmitCommandDetails(), lContext).ConfigureAwait(false); if (lResult.ResultType == eCommandResultType.ok) { lContext.TraceInformation("fetch body success"); if (lHook.Body == null) { throw new cRequestedDataNotReturnedException(lContext); } return(lHook.Body); } if (lHook.Body != null) { lContext.TraceError("received body on a failed fetch body"); } fCapabilities lTryIgnoring; if (pBinary) { lTryIgnoring = fCapabilities.binary; } else { lTryIgnoring = 0; } if (lResult.ResultType == eCommandResultType.no) { throw new cUnsuccessfulCompletionException(lResult.ResponseText, lTryIgnoring, lContext); } throw new cProtocolErrorException(lResult, lTryIgnoring, lContext); } }
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 cSetUnseenCountCommandHook(cSelectedMailbox pSelectedMailbox) : base(pSelectedMailbox) { }
public cCommandHookStore(cStoreFeedbackCollector pFeedbackCollector, cUIDStoreFeedback pUIDStoreFeedback, cSelectedMailbox pSelectedMailbox) { mFeedbackCollector = pFeedbackCollector ?? throw new ArgumentNullException(nameof(pFeedbackCollector)); mUIDStoreFeedback = pUIDStoreFeedback; mSelectedMailbox = pSelectedMailbox ?? throw new ArgumentNullException(nameof(pSelectedMailbox)); }
private async Task <cCopyFeedback> ZCopyAsync(cMethodControl pMC, cMessageHandleList pSourceMessageHandles, cMailboxCacheItem pDestinationItem, cTrace.cContext pParentContext) { var lContext = pParentContext.NewMethod(nameof(cSession), nameof(ZCopyAsync), pMC, pSourceMessageHandles, pDestinationItem); using (var lBuilder = new cCommandDetailsBuilder()) { lBuilder.Add(await mSelectExclusiveAccess.GetBlockAsync(pMC, lContext).ConfigureAwait(false)); // block select cSelectedMailbox lSelectedMailbox = mMailboxCache.CheckInSelectedMailbox(pSourceMessageHandles); 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 var lUIDValidity = lSelectedMailbox.MessageCache.UIDValidity; lBuilder.AddUIDValidity(lUIDValidity); // resolve the handles to MSNs cUIntList lMSNs = new cUIntList(); foreach (var lMessageHandle in pSourceMessageHandles) { var lMSN = lSelectedMailbox.GetMSN(lMessageHandle); if (lMSN == 0) { if (lMessageHandle.Expunged) { throw new cMessageExpungedException(lMessageHandle); } else { throw new ArgumentOutOfRangeException(nameof(pSourceMessageHandles)); } } lMSNs.Add(lMSN); } // build the command lBuilder.Add(kCopyCommandPart, new cTextCommandPart(cSequenceSet.FromUInts(lMSNs)), cCommandPart.Space, pDestinationItem.MailboxNameCommandPart); // add the hook var lHook = new cCommandHookCopy(lUIDValidity); lBuilder.Add(lHook); // submit the command var lResult = await mPipeline.ExecuteAsync(pMC, lBuilder.EmitCommandDetails(), lContext).ConfigureAwait(false); if (lResult.ResultType == eCommandResultType.ok) { lContext.TraceInformation("copy success"); return(lHook.Feedback); } if (lResult.ResultType == eCommandResultType.no) { throw new cUnsuccessfulCompletionException(lResult.ResponseText, 0, lContext); } throw new cProtocolErrorException(lResult, 0, lContext); } }
private readonly bool mSort; // if the results are coming sorted this should be set to true public cCommandHookSearchExtended(cCommandTag pCommandTag, cSelectedMailbox pSelectedMailbox, bool pSort) : base(pCommandTag, pSelectedMailbox) { mSort = pSort; }
public cSetUnseenCountExtendedCommandHook(cCommandTag pCommandTag, cSelectedMailbox pSelectedMailbox) : base(pCommandTag, pSelectedMailbox) { }
private async Task ZStoreAsync(cMethodControl pMC, cStoreFeedback pFeedback, eStoreOperation pOperation, cStorableFlags pFlags, ulong?pIfUnchangedSinceModSeq, cTrace.cContext pParentContext) { var lContext = pParentContext.NewMethod(nameof(cSession), nameof(ZStoreAsync), pMC, pFeedback, pOperation, pFlags, pIfUnchangedSinceModSeq); // no validation ... all the parameters have been validated already by the cSession by the time we get here using (var lBuilder = new cCommandDetailsBuilder()) { lBuilder.Add(await mSelectExclusiveAccess.GetBlockAsync(pMC, lContext).ConfigureAwait(false)); // block select cSelectedMailbox lSelectedMailbox = mMailboxCache.CheckInSelectedMailbox(pFeedback); if (!lSelectedMailbox.SelectedForUpdate) { throw new InvalidOperationException(kInvalidOperationExceptionMessage.NotSelectedForUpdate); } 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); // collector cStoreFeedbackCollector lFeedbackCollector = new cStoreFeedbackCollector(); // resolve the handles to MSNs foreach (var lItem in pFeedback) { var lMSN = lSelectedMailbox.GetMSN(lItem.MessageHandle); if (lMSN != 0) { lFeedbackCollector.Add(lMSN, lItem); } } // if no handles were resolved, we are done if (lFeedbackCollector.Count == 0) { return; } // build the command lBuilder.Add(kStoreCommandPartStoreSpace, new cTextCommandPart(cSequenceSet.FromUInts(lFeedbackCollector.UInts)), cCommandPart.Space); if (pIfUnchangedSinceModSeq != null) { lBuilder.Add(kStoreCommandPartLParenUnchangedSinceSpace, new cTextCommandPart(pIfUnchangedSinceModSeq.Value), kStoreCommandPartRParenSpace); } lBuilder.Add(pOperation, pFlags); // add the hook var lHook = new cCommandHookStore(lFeedbackCollector, null, lSelectedMailbox); lBuilder.Add(lHook); // submit the command var lResult = await mPipeline.ExecuteAsync(pMC, lBuilder.EmitCommandDetails(), lContext).ConfigureAwait(false); // NOTE: updates may have been done on both OK and NO responses (see rfc 2180/ 7162) so we can't throw on a NO for this command ... NO indicates that some (or all) of the messages have pending deletes // throw on a bad if (lResult.ResultType == eCommandResultType.bad) { fCapabilities lTryIgnoring; if (pIfUnchangedSinceModSeq == null) { lTryIgnoring = 0; } else { lTryIgnoring = fCapabilities.condstore; } throw new cProtocolErrorException(lResult, lTryIgnoring, lContext); } if (lResult.ResultType == eCommandResultType.ok) { lContext.TraceInformation("store success"); } else { lContext.TraceInformation("store possible partial success"); } } }
public cSortCommandHook(cSelectedMailbox pSelectedMailbox) { mSelectedMailbox = pSelectedMailbox ?? throw new ArgumentNullException(nameof(pSelectedMailbox)); }
public cCommandHookBaseSearchExtended(cCommandTag pCommandTag, cSelectedMailbox pSelectedMailbox) { mCommandTag = pCommandTag ?? throw new ArgumentNullException(nameof(pCommandTag)); mSelectedMailbox = pSelectedMailbox ?? throw new ArgumentNullException(nameof(pSelectedMailbox)); }
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); }
public async Task FetchBinarySizeAsync(cMethodControl pMC, iMessageHandle pMessageHandle, string pPart, cTrace.cContext pParentContext) { var lContext = pParentContext.NewMethod(nameof(cSession), nameof(FetchBinarySizeAsync), pMC, pMessageHandle, pPart); if (mDisposed) { throw new ObjectDisposedException(nameof(cSession)); } if (_ConnectionState != eConnectionState.selected) { throw new InvalidOperationException(kInvalidOperationExceptionMessage.NotSelected); } if (pMessageHandle == null) { throw new ArgumentNullException(nameof(pMessageHandle)); } if (pPart == null) { throw new ArgumentNullException(nameof(pPart)); } if (!cCommandPartFactory.TryAsAtom(pPart, out var lPart)) { throw new ArgumentOutOfRangeException(nameof(pPart)); } using (var lBuilder = new cCommandDetailsBuilder()) { lBuilder.Add(await mSelectExclusiveAccess.GetBlockAsync(pMC, lContext).ConfigureAwait(false)); // block select cSelectedMailbox lSelectedMailbox = mMailboxCache.CheckInSelectedMailbox(pMessageHandle); 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 the MSN uint lMSN = lSelectedMailbox.GetMSN(pMessageHandle); if (lMSN == 0) { if (pMessageHandle.Expunged) { throw new cMessageExpungedException(pMessageHandle); } else { throw new ArgumentOutOfRangeException(nameof(pMessageHandle)); } } // build command lBuilder.Add(kFetchCommandPartFetchSpace, new cTextCommandPart(lMSN), kFetchCommandPartSpaceBinarySizeLBracket, lPart, cCommandPart.RBracket); // go var lResult = await mPipeline.ExecuteAsync(pMC, lBuilder.EmitCommandDetails(), lContext).ConfigureAwait(false); if (lResult.ResultType == eCommandResultType.ok) { lContext.TraceInformation("fetch binary.size success"); return; } if (lResult.ResultType == eCommandResultType.no) { throw new cUnsuccessfulCompletionException(lResult.ResponseText, fCapabilities.binary, lContext); } throw new cProtocolErrorException(lResult, fCapabilities.binary, lContext); } }
public cSearchCommandHook(cSelectedMailbox pSelectedMailbox) : base(pSelectedMailbox) { }