/// <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; }
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; }