private void MergePendingDeletes(FolderChangesManifest changes, IReadOnlyCollection <string> pendingDeletes) { if (pendingDeletes.Count == 0) { return; } List <DeleteCommand> list = new List <DeleteCommand>(pendingDeletes.Count); foreach (string serverId in pendingDeletes) { list.Add(new DeleteCommand { ServerId = serverId }); } using (IEnumerator <MessageRec> enumerator2 = base.CreateMessageRecsForDeletions(list).GetEnumerator()) { while (enumerator2.MoveNext()) { MessageRec messageRec = enumerator2.Current; if (changes.ChangedMessages.Find((MessageRec rec) => ArrayComparer <byte> .EqualityComparer.Equals(rec.EntryId, messageRec.EntryId)) == null) { changes.ChangedMessages.Add(messageRec); } } } }
private void EnumerateIncrementalChanges(FolderChangesManifest changes, IReadOnlyCollection <MessageRec> messageRecs) { if (messageRecs.Count == 0) { return; } foreach (MessageRec messageRec in messageRecs) { switch (EasSourceFolder.FindMessageCategory(messageRec)) { case EasMessageCategory.AddOrUpdate: case EasMessageCategory.Delete: changes.ChangedMessages.Add(messageRec); break; case EasMessageCategory.ChangeToRead: changes.ReadMessages.Add(messageRec.EntryId); break; case EasMessageCategory.ChangeToUnread: changes.UnreadMessages.Add(messageRec.EntryId); break; } } }
FolderChangesManifest ISourceFolder.EnumerateChanges(EnumerateContentChangesFlags flags, int maxChanges) { FolderChangesManifest folderChangesManifest = new FolderChangesManifest(base.FolderId); folderChangesManifest.ChangedMessages = new List <MessageRec>(); folderChangesManifest.ReadMessages = new List <byte[]>(); folderChangesManifest.UnreadMessages = new List <byte[]>(); SyncContentsManifestState syncContentsManifestState = base.Mailbox.SyncState[base.FolderId]; PopFolderState lastSyncedState; if (syncContentsManifestState.Data != null) { lastSyncedState = PopFolderState.Deserialize(syncContentsManifestState.Data); } else { lastSyncedState = PopFolderState.CreateNew(); } List <MessageRec> messages = base.EnumerateMessagesOnPopConnection(maxChanges); PopFolderState popFolderState = PopFolderState.Create(messages); this.EnumerateIncrementalChanges(popFolderState, lastSyncedState, folderChangesManifest, messages); syncContentsManifestState.Data = popFolderState.Serialize(); return(folderChangesManifest); }
private void ConfigureMapiManifest(SyncContentsManifestState syncState, FolderChangesManifest changes, EnumerateContentChangesFlags flags, int maxChanges) { if (this.isPagedEnumeration && !flags.HasFlag(EnumerateContentChangesFlags.FirstPage)) { this.callback.InitializeNextPage(changes, maxChanges); return; } this.callback = new ManifestContentsCallback(this.folder.GetFolderId(), this.isPagedEnumeration); this.callback.InitializeNextPage(changes, maxChanges); ManifestConfigFlags manifestConfigFlags = ManifestConfigFlags.Associated | ManifestConfigFlags.Normal | ManifestConfigFlags.OrderByDeliveryTime; if (flags.HasFlag(EnumerateContentChangesFlags.Catchup)) { manifestConfigFlags |= ManifestConfigFlags.Catchup; } Restriction restriction = ((this.mailbox.Options & MailboxOptions.IgnoreExtendedRuleFAIs) != MailboxOptions.None) ? ContentChangesFetcherUtils.ExcludeAllRulesRestriction : ContentChangesFetcherUtils.ExcludeV40RulesRestriction; using (this.mailbox.RHTracker.Start()) { this.mapiManifest = this.mapiFolder.CreateExportManifest(); } using (MemoryStream memoryStream = (syncState.Data != null) ? new MemoryStream(syncState.Data) : null) { using (this.mailbox.RHTracker.Start()) { this.mapiManifest.Configure(manifestConfigFlags, restriction, memoryStream, this.callback, new PropTag[0]); } } }
public void InitializeNextPage(FolderChangesManifest folderChangesManifest, int maxChanges) { this.changes = folderChangesManifest; this.changes.ChangedMessages = new List <MessageRec>((!this.isPagedEnumeration) ? 0 : maxChanges); this.changes.ReadMessages = new List <byte[]>(); this.changes.UnreadMessages = new List <byte[]>(); this.maxChanges = maxChanges; this.countEnumeratedChanges = 0; bool flag = this.isPagedEnumeration; }
FolderChangesManifest ISourceFolder.EnumerateChanges(EnumerateContentChangesFlags flags, int maxChanges) { FolderChangesManifest result = null; base.CreateContext("ISourceFolder.EnumerateChanges", new DataContext[] { new SimpleValueDataContext("flags", flags), new SimpleValueDataContext("maxChanges", maxChanges) }).Execute(delegate { result = ((ISourceFolder)this.WrappedObject).EnumerateChanges(flags, maxChanges); }, true); return(result); }
private void ApplyFolderChanges(SyncContext ctx, FolderChangesManifest folderChanges, FolderMapping fm, ISourceFolder srcFolder, IDestinationFolder destFolder) { int num = 0; int num2 = 0; int num3 = 0; int num4 = 0; int num5 = 0; FolderContentsMapper folderContentsMapper = FolderContentsMapper.Create(fm, srcFolder, this.SourceHierarchy, destFolder, this.DestHierarchy, base.MRSJob.CachedRequestJob.ConflictResolutionOption ?? ConflictResolutionOption.KeepSourceItem, base.MRSJob.CachedRequestJob.AssociatedMessagesCopyOption ?? FAICopyOption.DoNotCopy, (base.MRSJob.CachedRequestJob.SyncProtocol == SyncProtocol.Imap) ? FolderContentsMapperFlags.ImapSync : FolderContentsMapperFlags.None); List <MessageRec> list; byte[][] array; byte[][] array2; byte[][] array3; int skipped; folderContentsMapper.ComputeIncrementalMapping(folderChanges, (base.SyncState == null) ? null : base.SyncState.BadItems, out list, out array, out array2, out array3, out skipped); this.CopyMessageBatch(folderContentsMapper, list, fm); destFolder.DeleteMessages(array); destFolder.SetReadFlagsOnMessages(SetReadFlags.None, array2); destFolder.SetReadFlagsOnMessages(SetReadFlags.ClearRead, array3); if (list != null) { foreach (MessageRec messageRec in list) { if (messageRec.IsNew) { num++; } else { num2++; } } } if (array != null) { num3 += array.Length; } if (array2 != null) { num4 += array2.Length; } if (array3 != null) { num5 += array3.Length; } ctx.CopyMessagesCount += new CopyMessagesCount(num, num2, num3, num4, num5, skipped); }
public FolderChangesManifest this[byte[] folderId] { get { FolderChangesManifest folderChangesManifest; if (!this.folderChanges.TryGetValue(folderId, out folderChangesManifest)) { folderChangesManifest = new FolderChangesManifest(folderId); this.folderChanges.Add(folderId, folderChangesManifest); } return(folderChangesManifest); } set { this.folderChanges[folderId] = value; } }
FolderChangesManifest IContentChangesFetcher.EnumerateContentChanges(SyncContentsManifestState syncState, EnumerateContentChangesFlags flags, int maxChanges) { FolderChangesManifest folderChangesManifest = this.EnumerateChanges(syncState, flags, maxChanges); if (MrsTracer.Provider.IsEnabled(TraceType.DebugTrace)) { int num; int num2; int num3; folderChangesManifest.GetMessageCounts(out num, out num2, out num3); MrsTracer.Provider.Debug("Discovered {0} new, {1} changed, {2} deleted, {3} read, {4} unread.", new object[] { num, num2, num3, folderChangesManifest.ReadMessages.Count, folderChangesManifest.UnreadMessages.Count }); } return(folderChangesManifest); }
private FolderChangesManifest EnumerateChanges(SyncContentsManifestState syncState, EnumerateContentChangesFlags flags, int maxChanges) { FolderChangesManifest folderChangesManifest = new FolderChangesManifest(this.folder.GetFolderId()); if (this.folder.GetFolderRec(null, GetFolderRecFlags.None).FolderType == FolderType.Search) { return(folderChangesManifest); } this.ConfigureMapiManifest(syncState, folderChangesManifest, flags, maxChanges); ManifestStatus manifestStatus; do { manifestStatus = this.mapiManifest.Synchronize(); }while (manifestStatus != ManifestStatus.Done && manifestStatus != ManifestStatus.Yielded); using (MemoryStream memoryStream = new MemoryStream()) { this.mapiManifest.GetState(memoryStream); syncState.Data = memoryStream.ToArray(); } return(folderChangesManifest); }
FolderChangesManifest ISourceFolder.EnumerateChanges(EnumerateContentChangesFlags flags, int maxChanges) { FolderChangesManifest folderChangesManifest = base.CreateInitializedChangesManifest(); SyncContentsManifestState syncContentsManifestState = base.Mailbox.SyncState[base.EntryId]; EasFolderSyncState persistedSyncState = base.Mailbox.GetPersistedSyncState(syncContentsManifestState); string syncKey = persistedSyncState.SyncKey; EasSyncOptions options = new EasSyncOptions { SyncKey = syncKey, RecentOnly = true, MaxNumberOfMessage = 512 }; EasSyncResult easSyncResult = base.SyncMessages(base.Mailbox.EasConnectionWrapper, options); List <MessageRec> messageRecs = easSyncResult.MessageRecs; this.EnumerateIncrementalChanges(folderChangesManifest, messageRecs); this.MergePendingDeletes(folderChangesManifest, persistedSyncState.CrawlerDeletions); persistedSyncState.SyncKey = easSyncResult.NewSyncKey; persistedSyncState.ChangesSynced = new DateTime?(DateTime.UtcNow); persistedSyncState.CrawlerDeletions.Clear(); syncContentsManifestState.Data = persistedSyncState.Serialize(); return(folderChangesManifest); }
FolderChangesManifest ISourceFolder.EnumerateChanges(EnumerateContentChangesFlags flags, int maxChanges) { FolderChangesManifest folderChangesManifest = new FolderChangesManifest(base.FolderId); folderChangesManifest.ChangedMessages = new List <MessageRec>(); folderChangesManifest.ReadMessages = new List <byte[]>(); folderChangesManifest.UnreadMessages = new List <byte[]>(); if (!base.Folder.IsSelectable) { return(folderChangesManifest); } SyncContentsManifestState syncContentsManifestState = base.Mailbox.SyncState[base.FolderId]; ImapFolderState imapFolderState; if (syncContentsManifestState.Data != null) { imapFolderState = ImapFolderState.Deserialize(syncContentsManifestState.Data); if (imapFolderState.UidValidity != base.Folder.UidValidity) { syncContentsManifestState.Data = ImapFolderState.CreateNew(base.Folder).Serialize(); this.nextSeqNumCrawl = null; folderChangesManifest.FolderRecoverySync = true; return(folderChangesManifest); } } else { imapFolderState = ImapFolderState.CreateNew(base.Folder); } List <MessageRec> messages = base.EnumerateMessages(FetchMessagesFlags.None, null, null); ImapFolderState imapFolderState2 = ImapFolderState.Create(messages, imapFolderState.SeqNumCrawl, base.Folder.UidNext, base.Folder.UidValidity); this.EnumerateIncrementalChanges(imapFolderState2, imapFolderState, folderChangesManifest, messages); syncContentsManifestState.Data = imapFolderState2.Serialize(); return(folderChangesManifest); }
private void EnumerateIncrementalChanges(ImapFolderState currentState, ImapFolderState lastSyncedState, FolderChangesManifest changes, IEnumerable <MessageRec> messages) { Dictionary <uint, MessageRec> dictionary = new Dictionary <uint, MessageRec>(); foreach (MessageRec messageRec in messages) { uint key = ImapEntryId.ParseUid(messageRec.EntryId); dictionary.Add(key, messageRec); } this.EnumerateNewMessages(currentState, lastSyncedState, changes, dictionary); this.EnumerateReadUnreadFlagChanges(currentState, lastSyncedState, changes, dictionary); this.EnumerateMessageDeletes(currentState, lastSyncedState, changes, dictionary); }
private void EnumerateNewMessages(ImapFolderState currentState, ImapFolderState lastSyncedState, FolderChangesManifest changes, Dictionary <uint, MessageRec> lookup) { if (lastSyncedState.UidNext == 0U || lastSyncedState.UidNext == 1U) { foreach (MessageRec messageRec in lookup.Values) { messageRec.Flags |= MsgRecFlags.New; changes.ChangedMessages.Add(messageRec); } return; } for (uint num = currentState.UidNext - 1U; num > lastSyncedState.UidNext - 1U; num -= 1U) { MessageRec messageRec2 = null; if (lookup.TryGetValue(num, out messageRec2)) { messageRec2.Flags |= MsgRecFlags.New; changes.ChangedMessages.Add(messageRec2); } } }
private void EnumerateMessageDeletes(ImapFolderState currentState, ImapFolderState lastSyncedState, FolderChangesManifest changes, Dictionary <uint, MessageRec> lookup) { Action <uint> uidInclusionAction = delegate(uint uid) { MessageRec item = new MessageRec(ImapEntryId.CreateMessageEntryId(uid, this.Folder.UidValidity, this.Folder.Name, this.Mailbox.ImapConnection.ConnectionContext.UserName), this.FolderId, CommonUtils.DefaultLastModificationTime, 0, MsgRecFlags.Deleted, Array <PropValueData> .Empty); changes.ChangedMessages.Add(item); }; Action <uint> uidExclusionAction = delegate(uint uid) { MessageRec item = null; if (lookup.TryGetValue(uid, out item)) { changes.ChangedMessages.Add(item); } }; ImapFolderState.EnumerateMessageDeletes(currentState, lastSyncedState, uidInclusionAction, uidExclusionAction); }
private void EnumerateReadUnreadFlagChanges(ImapFolderState currentState, ImapFolderState lastSyncedState, FolderChangesManifest changes, Dictionary <uint, MessageRec> lookup) { Action <uint> uidInclusionAction = delegate(uint uid) { MessageRec messageRec = null; if (lookup.TryGetValue(uid, out messageRec)) { changes.ReadMessages.Add(messageRec.EntryId); } }; Action <uint> uidExclusionAction = delegate(uint uid) { MessageRec messageRec = null; if (lookup.TryGetValue(uid, out messageRec)) { changes.UnreadMessages.Add(messageRec.EntryId); } }; ImapFolderState.EnumerateReadUnreadFlagChanges(currentState, lastSyncedState, uidInclusionAction, uidExclusionAction); }
public void ComputeIncrementalMapping(FolderChangesManifest folderChanges, EntryIdMap <BadItemMarker> badItemMarkers, out List <MessageRec> itemsToCopy, out byte[][] deletedTargetEntryIDs, out byte[][] readTargetEntryIDs, out byte[][] unreadTargetEntryIDs, out int skippedItemCount) { MrsTracer.Service.Function("FolderContentsMapper.ComputeIncrementalMapping", new object[0]); skippedItemCount = 0; itemsToCopy = null; deletedTargetEntryIDs = null; readTargetEntryIDs = null; unreadTargetEntryIDs = null; List <byte[]> list = new List <byte[]>(); List <byte[]> list2 = new List <byte[]>(); List <byte[]> list3 = new List <byte[]>(); if (folderChanges.ChangedMessages != null) { foreach (MessageRec messageRec in folderChanges.ChangedMessages) { list2.Add(messageRec.EntryId); if (!messageRec.IsDeleted) { list.Add(messageRec.EntryId); } else { list3.Add(messageRec.EntryId); } } } if (folderChanges.ReadMessages != null) { list2.AddRange(folderChanges.ReadMessages); } if (folderChanges.UnreadMessages != null) { list2.AddRange(folderChanges.UnreadMessages); } if (list2.Count == 0) { return; } list2.Sort(ArrayComparer <byte> .Comparer); List <PropTag> list4 = new List <PropTag>(); list4.Add(PropTag.SearchKey); list4.Add(PropTag.LastModificationTime); list4.Add(PropTag.MessageClass); List <MessageRec> list5 = null; if (list.Count > 0) { MrsTracer.Service.Debug("Loading changed source messages", new object[0]); list.Sort(ArrayComparer <byte> .Comparer); list5 = this.srcFolder.LookupMessages(PropTag.EntryId, list, list4.ToArray()); } EntryIdMap <MessageRec> entryIdMap = new EntryIdMap <MessageRec>(); if (this.conflictResolutionOption != ConflictResolutionOption.KeepAll) { list4.Add(this.destHierarchy.SourceEntryIDPtag); list4.Add(this.destHierarchy.SourceLastModifiedTimestampPtag); MrsTracer.Service.Debug("Looking up target messages", new object[0]); List <MessageRec> list6 = this.destFolder.LookupMessages(this.destHierarchy.SourceEntryIDPtag, list2, list4.ToArray()); foreach (MessageRec messageRec2 in list6) { byte[] array = messageRec2[this.destHierarchy.SourceEntryIDPtag] as byte[]; if (array != null) { this.targetMapping[array] = messageRec2; } byte[] keyPlusLMTHash = this.GetKeyPlusLMTHash(messageRec2, this.destHierarchy.SourceEntryIDPtag, this.destHierarchy.SourceLastModifiedTimestampPtag); if (keyPlusLMTHash != null) { entryIdMap[keyPlusLMTHash] = messageRec2; } } } if (list5 == null) { MrsTracer.Service.Debug("ChangedSourceIds {0}, SourceMessages looked up is null", new object[] { list.Count }); } else { if (list5.Count != list.Count) { MrsTracer.Service.Debug("ChangedSourceIds {0}, SourceMessages looked up {1}", new object[] { list.Count, list5.Count }); } itemsToCopy = new List <MessageRec>(); foreach (MessageRec messageRec3 in list5) { string text; if (FolderContentsMapper.ShouldItemBeIgnored(messageRec3, badItemMarkers, this.faiCopyOption, out text)) { skippedItemCount++; } else { MessageRec messageRec4 = null; this.MapSourceToTargetMessageBySourceEntryId(messageRec3, entryIdMap, out messageRec4); if (!this.ShouldItemBeCopied(messageRec3, messageRec4, null)) { skippedItemCount++; } else { if (messageRec4 == null) { messageRec3.Flags |= MsgRecFlags.New; } itemsToCopy.Add(messageRec3); this.sourceMapping[messageRec3.EntryId] = messageRec3; } } } } if (list3.Count > 0) { deletedTargetEntryIDs = this.RemapSourceIDsToTargetIDs(list3); } if (folderChanges.ReadMessages != null && folderChanges.ReadMessages.Count > 0) { readTargetEntryIDs = this.RemapSourceIDsToTargetIDs(folderChanges.ReadMessages); } if (folderChanges.UnreadMessages != null && folderChanges.UnreadMessages.Count > 0) { unreadTargetEntryIDs = this.RemapSourceIDsToTargetIDs(folderChanges.UnreadMessages); } }
private void EnumerateMessageDeletes(PopFolderState currentState, PopFolderState lastSyncedState, FolderChangesManifest changes, Dictionary <string, MessageRec> lookup) { foreach (string text in lastSyncedState.MessageList.Values) { if (!currentState.MessageList.Contains(text)) { MessageRec messageRec = base.CreateMessageRec(text, 0L); messageRec.Flags |= MsgRecFlags.Deleted; changes.ChangedMessages.Add(messageRec); } } }
FolderChangesManifest IContentChangesFetcher.EnumerateContentChanges(SyncContentsManifestState syncState, EnumerateContentChangesFlags enumerateFlags, int maxChanges) { FolderChangesManifest folderChangesManifest = new FolderChangesManifest(this.folder.GetFolderId()); bool flag = enumerateFlags.HasFlag(EnumerateContentChangesFlags.Catchup); ManifestContentsCallback manifestContentsCallback = new ManifestContentsCallback(this.folder.GetFolderId(), false); manifestContentsCallback.InitializeNextPage(folderChangesManifest, maxChanges); SyncConfigFlags syncConfigFlags = SyncConfigFlags.ReadState | SyncConfigFlags.Associated | SyncConfigFlags.Normal | SyncConfigFlags.OnlySpecifiedProps; if (flag) { syncConfigFlags |= SyncConfigFlags.Catchup; } PropTag[] propsInclude = new PropTag[] { PropTag.EntryId, PropTag.MessageSize }; MapiSynchronizer mapiSynchronizer; using (this.mailbox.RHTracker.Start()) { mapiSynchronizer = this.mapiFolder.CreateContentsSynchronizer(); } using (MapiManifestCollector mapiManifestCollector = new MapiManifestCollector(this.mapiFolder, manifestContentsCallback)) { using (mapiSynchronizer) { using (MemoryStream memoryStream = new MemoryStream()) { if (syncState.Data != null) { memoryStream.Write(syncState.Data, 0, syncState.Data.Length); memoryStream.Position = 0L; } Restriction restriction = ((this.mailbox.Options & MailboxOptions.IgnoreExtendedRuleFAIs) != MailboxOptions.None) ? ContentChangesFetcherUtils.ExcludeAllRulesRestriction : ContentChangesFetcherUtils.ExcludeV40RulesRestriction; using (this.mailbox.RHTracker.Start()) { mapiSynchronizer.Config(memoryStream, syncConfigFlags, mapiManifestCollector, restriction, propsInclude, null); while (mapiSynchronizer.Synchronize() != 0) { } } syncState.Data = memoryStream.ToArray(); } } } if (!flag && MrsTracer.Provider.IsEnabled(TraceType.DebugTrace)) { int num; int num2; int num3; folderChangesManifest.GetMessageCounts(out num, out num2, out num3); MrsTracer.Provider.Debug("Discovered {0} new, {1} changed, {2} deleted, {3} read, {4} unread.", new object[] { num, num2, num3, folderChangesManifest.ReadMessages.Count, folderChangesManifest.UnreadMessages.Count }); } return(folderChangesManifest); }
private void EnumerateNewMessages(PopFolderState currentState, PopFolderState lastSyncedState, FolderChangesManifest changes, Dictionary <string, MessageRec> lookup) { foreach (string text in currentState.MessageList.Values) { if (!lastSyncedState.MessageList.Contains(text)) { MessageRec messageRec = null; if (lookup.TryGetValue(text, out messageRec)) { messageRec.Flags |= MsgRecFlags.New; changes.ChangedMessages.Add(messageRec); } } } }