Пример #1
0
        public static cUIDList FromUID(cUID pUID)
        {
            if (pUID == null)
            {
                throw new ArgumentNullException(nameof(pUID));
            }
            var lResult = new cUIDList();

            lResult.Add(pUID);
            return(lResult);
        }
Пример #2
0
        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);
        }
Пример #3
0
            private async Task ZFetchCacheItemsAsync(cMethodControl pMC, cFetchCacheItemsGroup pGroup, cProgress pProgress, cTrace.cContext pParentContext)
            {
                var lContext = pParentContext.NewMethod(nameof(cSession), nameof(ZFetchCacheItemsAsync), pMC, pGroup);

                if (pGroup.Items.IsEmpty)
                {
                    // the group where we already have everything that we need
                    pProgress.Increment(pGroup.MessageHandles.Count, lContext);
                    return;
                }

                int      lExpungedCount;
                int      lIndex = 0;
                cUIDList lUIDs  = new cUIDList();

                if (pGroup.MSNHandleCount > 0)
                {
                    // this is where we use straight fetch (not UID fetch)
                    //////////////////////////////////////////////////////

                    // sort the handles so we might get good sequence sets
                    pGroup.MessageHandles.SortByCacheSequence();

                    int       lMSNHandleCount = pGroup.MSNHandleCount;
                    Stopwatch lStopwatch      = new Stopwatch();

                    while (lIndex < pGroup.MessageHandles.Count && lMSNHandleCount != 0)
                    {
                        // the number of messages to fetch this time
                        int lFetchCount = mFetchCacheItemsSizer.Current;

                        // the number of UID handles we need to fetch to top up the number of handles to the limit
                        //
                        int lUIDHandleCount;
                        if (lFetchCount > lMSNHandleCount)
                        {
                            lUIDHandleCount = lFetchCount - lMSNHandleCount;
                        }
                        else
                        {
                            lUIDHandleCount = 0;
                        }

                        // get the handles to fetch this time

                        lExpungedCount = 0;
                        cMessageHandleList lMessageHandles = new cMessageHandleList();

                        while (lIndex < pGroup.MessageHandles.Count && lMessageHandles.Count < lFetchCount)
                        {
                            var lMessageHandle = pGroup.MessageHandles[lIndex++];

                            if (lMessageHandle.Expunged)
                            {
                                lExpungedCount++;
                            }
                            else
                            {
                                if (lMessageHandle.UID == null)
                                {
                                    lMessageHandles.Add(lMessageHandle);
                                    lMSNHandleCount--;
                                }
                                else if (lUIDHandleCount > 0)
                                {
                                    lMessageHandles.Add(lMessageHandle);
                                    lUIDHandleCount--;
                                }
                                else
                                {
                                    lUIDs.Add(lMessageHandle.UID);
                                }
                            }
                        }

                        // if other fetching is occurring at the same time (retrieving UIDs) then there mightn't be any
                        //
                        if (lMessageHandles.Count > 0)
                        {
                            // fetch
                            lStopwatch.Restart();
                            await ZFetchCacheItemsAsync(pMC, lMessageHandles, pGroup.Items, lContext).ConfigureAwait(false);

                            lStopwatch.Stop();

                            // store the time taken so the next fetch is a better size
                            mFetchCacheItemsSizer.AddSample(lMessageHandles.Count, lStopwatch.ElapsedMilliseconds);
                        }

                        // update progress
                        if (lExpungedCount > 0 || lMessageHandles.Count > 0)
                        {
                            pProgress.Increment(lExpungedCount + lMessageHandles.Count, lContext);
                        }
                    }
                }

                lExpungedCount = 0;

                while (lIndex < pGroup.MessageHandles.Count)
                {
                    var lMessageHandle = pGroup.MessageHandles[lIndex++];
                    if (lMessageHandle.Expunged)
                    {
                        lExpungedCount++;
                    }
                    else
                    {
                        lUIDs.Add(lMessageHandle.UID);
                    }
                }

                if (lExpungedCount > 0)
                {
                    pProgress.Increment(lExpungedCount, lContext);
                }

                if (lUIDs.Count == 0)
                {
                    return;
                }

                // uid fetch the remainder
                var lMailboxHandle = pGroup.MessageHandles[0].MessageCache.MailboxHandle;

                await ZUIDFetchCacheItemsAsync(pMC, lMailboxHandle, lUIDs, pGroup.Items, pProgress, lContext).ConfigureAwait(false);
            }
Пример #4
0
        private async Task <cCopyFeedback> ZUIDCopyAsync(iMailboxHandle pSourceMailboxHandle, cUIDList pSourceUIDs, iMailboxHandle pDestinationMailboxHandle, cTrace.cContext pParentContext)
        {
            var lContext = pParentContext.NewMethod(nameof(cIMAPClient), nameof(ZCopyAsync), pSourceMailboxHandle, pSourceUIDs, pDestinationMailboxHandle);

            if (mDisposed)
            {
                throw new ObjectDisposedException(nameof(cIMAPClient));
            }

            var lSession = mSession;

            if (lSession == null || lSession.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)
            {
                return(null);
            }

            using (var lToken = mCancellationManager.GetToken(lContext))
            {
                var lMC = new cMethodControl(mTimeout, lToken.CancellationToken);
                return(await lSession.UIDCopyAsync(lMC, pSourceMailboxHandle, pSourceUIDs, pDestinationMailboxHandle, lContext).ConfigureAwait(false));
            }
        }
Пример #5
0
            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);
            }
Пример #6
0
            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);
                }
            }
Пример #7
0
            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));
            }