public override eProcessDataResult ProcessData(cBytesCursor pCursor, cTrace.cContext pParentContext) { var lContext = pParentContext.NewMethod(nameof(cCommandHookBaseSearch), nameof(ProcessData)); if (!pCursor.SkipBytes(kSearch)) { return(eProcessDataResult.notprocessed); } cUIntList lMSNs = new cUIntList(); while (true) { if (!pCursor.SkipByte(cASCII.SPACE)) { break; } if (!pCursor.GetNZNumber(out _, out var lMSN)) { lContext.TraceWarning("likely malformed search: not an nz-number list?"); return(eProcessDataResult.notprocessed); } lMSNs.Add(lMSN); } if (!pCursor.Position.AtEnd) { lContext.TraceWarning("likely malformed search: not at end?"); return(eProcessDataResult.notprocessed); } if (mMSNs == null) { mMSNs = lMSNs; } else { mMSNs.AddRange(lMSNs); } return(eProcessDataResult.processed); }
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 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); } }
private static bool ZExpand(cSequenceSet pSequenceSet, int pAsterisk, out cUIntList rResult) { if (pSequenceSet == null) { rResult = null; return(false); } rResult = new cUIntList(); foreach (var lItem in pSequenceSet) { if (lItem == cSequenceSetItem.Asterisk) { if (pAsterisk < 1) { return(false); } rResult.Add((uint)pAsterisk); continue; } if (lItem is cSequenceSetNumber lNumber) { rResult.Add(lNumber.Number); continue; } if (!(lItem is cSequenceSetRange lRange)) { return(false); } if (lRange.From == cSequenceSetItem.Asterisk) { if (pAsterisk < 1) { return(false); } rResult.Add((uint)pAsterisk); continue; } if (!(lRange.From is cSequenceSetNumber lFrom)) { return(false); } uint lTo; if (lRange.To == cSequenceSetItem.Asterisk) { if (pAsterisk < 1) { return(false); } lTo = (uint)pAsterisk; } else { if (!(lRange.To is cSequenceSetNumber lRangeTo)) { return(false); } lTo = lRangeTo.Number; } for (uint i = lFrom.Number; i <= lTo; i++) { rResult.Add(i); } } return(true); }
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); } }