Пример #1
0
        /// <summary>
        /// Fetch Mail Header for a list of UIDs (or IDs).
        /// </summary>
        /// <param name="ids">
        /// Depending on <see cref="EnableUidCommands"/> this is an array of UIDs 
        /// (<c>true</c>) or IDs (<c>false</c>).
        /// </param>
        /// <param name="what">
        /// A list of IMap items to be returned. If empty or null the default is:
        /// "<c>(UID FLAGS RFC822.SIZE BODY.PEEK[HEADER])</c>".
        /// </param>
        /// <returns>
        /// An array of mail headers (may be zero-sized) or <c>null</c> on error.
        /// </returns>
        /// <remarks>
        /// This method is used by <see cref="MailSearch(string, string, string[])"/>.
        /// It is recommended to set <see cref="EnableUidCommands"/> to <c>true</c>. 
        /// </remarks>
        public MailInfo[] MailHeaders(uint[] ids, string what)
        {
            if(factory == null || ids == null) return null;
            if(ids.Length <= 0) return new MailInfo[0];
            if(string.IsNullOrEmpty(what)) what = "UID FLAGS RFC822.SIZE BODY.PEEK[HEADER]";

            ZIMapCommand.Fetch fetch = new ZIMapCommand.Fetch(factory);
            if(fetch == null) return null;
            progress.Update(0);
            fetch.UidCommand = enableUid;

            uint count = (uint)ids.Length;
            uint block = fetchBlock;
            ZIMapCommand.Fetch.Item[] part = null;
            MailInfo[] rval = null;

            if(count <= block)
            {   fetch.Queue(ids, what);
                progress.Update(20);
                part = fetch.Items;
                if(part == null)
                {   MonitorError("MailHeaders: FETCH failed: " + fetch.Result.Message);
                    factory.DisposeCommands(null, false);
                    return null;
                }
                rval = new MailInfo[part.Length];
                for(uint irun=0; irun < part.Length; irun++)
                    rval[irun] = new MailInfo(part[irun]);
            }
            else
            {   List<MailInfo> items = new List<MailInfo>();
                uint last = 0;
                uint offs = 0;
                uint[] sub = null;
                while(count > 0)
                {   uint chunk = Math.Min(count, block);
                    if(chunk != last)
                    {   sub = new uint[chunk];
                        last = chunk;
                    }
                    Array.Copy(ids, offs, sub, 0, chunk);
                    progress.Update(offs, (uint)ids.Length);
                    fetch.Queue(sub, what);

                    part = fetch.Items;
                    if(part == null)
                    {   MonitorError("MailHeaders: FETCH failed: " + fetch.Result.Message);
                        factory.DisposeCommands(null, false);
                        return null;
                    }

                    foreach(ZIMapCommand.Fetch.Item item in part)
                        items.Add(new MailInfo(item));
                    fetch.Reset();
                    count -= chunk; offs += chunk;
                }
                rval = items.ToArray();
            }

            factory.DisposeCommands(null, false);
            if(rval == null) rval = new MailInfo[0];
            MonitorInfo("MailHeaders: Got " + rval.Length + " mails");
            progress.Done();
            return rval;
        }
Пример #2
0
        public MailInfo[] MailHeaders(uint firstIndex, uint lastIndex, string what)
        {
            if(what == null || what == "") what = "UID FLAGS RFC822.SIZE BODY.PEEK[HEADER]";
            if(lastIndex < firstIndex) return null;
            if(factory == null) return null;

            ZIMapCommand.Fetch fetch = new ZIMapCommand.Fetch(factory);
            if(fetch == null) return null;
            progress.Update(0);

            uint count = lastIndex - firstIndex;
            uint block = fetchBlock;
            uint progrcnt = 0;
            uint progrmax = count;
            List<MailInfo> items = null;
            ZIMapCommand.Fetch.Item[] part = null;

            while(count > 0)
            {   uint chunk = count; // Math.Min(count, block); // bug on mono?
                if(chunk > block) chunk = block;
                fetch.Reset();
                fetch.Queue(firstIndex, firstIndex+chunk-1, what);

                // semi logarithmic progress ...
                if(lastIndex == uint.MaxValue)
                {   if(progrcnt < 32*16)
                        progrcnt += 64;
                    else if(progrcnt < 64*16)
                        progrcnt += 16;
                    else if(progrcnt < 99)
                        progrcnt += 1;
                    progress.Update(progrcnt / 16);
                }
                // exact progress ...
                else
                {   progrcnt += block;
                    progress.Update(progrcnt, progrmax);
                }

                part = fetch.Items;
                if(part == null)
                {   if(fetch.CheckSuccess())
                        break;                      // server said: OK no more data
                    if(fetch.Result.State == ZIMapProtocol.ReceiveState.Error && items != null)
                        break;                      // server said: BAD no more data
                    if(fetch.Result.State == ZIMapProtocol.ReceiveState.Failure)
                        break;                      // server said: No no matching data
                    MonitorError("MailHeaders: FETCH failed: " + fetch.Result.Message);
                    factory.DisposeCommands(null, false);
                    return null;
                }

                // only one chunk, directly return the array
                if(count == chunk && items == null) break;

                // multiple chunks, store items in a list
                if(items == null)
                    items = new List<MailInfo>();
                foreach(ZIMapCommand.Fetch.Item item in part)
                    items.Add(new MailInfo(item));
                count -= chunk;
                firstIndex += chunk;
            }

            factory.DisposeCommands(null, false);
            MailInfo[] rval = null;
            if     (items != null) rval = items.ToArray();
            else if(part == null)  rval = new MailInfo[0];
            progress.Done();
            MonitorInfo("MailHeaders: Got " + rval.Length + " mails");
            return rval;
        }