/// <summary> /// Generate fast transfer stream data. /// </summary> /// <param name="serverId">server id.</param> /// <param name="buffer">Input buffer data.</param> /// <returns>AbstractFastTransferStream object.</returns> private AbstractFastTransferStream GenerateAbstractFastTransferStream( int serverId, byte[] buffer) { using (FastTransferStream fs = new FastTransferStream(buffer, false)) { AbstractFastTransferStream afts; // Record all property list generated while deserializing. SyntacticalBase.AllPropList = new List<PropList>(); int icsStateIndex = -1; switch (this.streamType) { case FastTransferStreamType.state: State s = new State(fs); this.VerifyMarkers(s); // Insert state to the ICSStateContainer icsStateIndex = this.InsertStateDict(s); afts = new AbstractFastTransferStream(); // Get the AbstractState corresponding to the state from the fast transfer stream. AbstractState astate = this.GetAbstractState(serverId, icsStateIndex, s); // Set the AbstractState of the AbstractFastTransferStream. afts.AbstractState = new AbstractState { AbstractICSStateIndex = icsStateIndex, IdSetGiven = astate.IdSetGiven }; //// Other fields of the AbstractState of the AbstractFastTransferStream do not need. afts.StreamType = FastTransferStreamType.state; return afts; case FastTransferStreamType.attachmentContent: AttachmentContent att = new AttachmentContent(fs); this.VerifyMarkers(att); return att.GetAbstractFastTransferStream(); case FastTransferStreamType.contentsSync: ContentsSync cs = new ContentsSync(fs); this.VerifyMarkers(cs); // Insert the state of the contentsSync to the ICSStateContainer icsStateIndex = this.InsertStateDict(cs.State); afts = this.GetAbstractContentSync( serverId, icsStateIndex, cs); return afts; case FastTransferStreamType.folderContent: FolderContent fc = new FolderContent(fs); this.VerifyMarkers(fc); this.VerifyFolderReplicaInfoStructure(fc); afts = fc.GetAbstractFastTransferStream(); if (!this.existNoPermissionFolder) { afts.AbstractFolderContent.IsNoPermissionObjNotOut = false; } this.VerifyMetaProperty(afts); return afts; case FastTransferStreamType.hierarchySync: HierarchySync hs = new HierarchySync(fs); this.VerifyMarkers(hs); if (hs.FolderChangeList.Count > 0) { PropValue property = hs.FolderChangeList[hs.FolderChangeList.Count - 1].PropList.PropValues.Find(p => p.PropInfo.PropID == 0x65e3); if (property != null) { this.lastConflictInfo.PCLXFromServer = ((VarPropTypePropValue)property).ValueArray; this.VerifyPidTagPredecessorChangeList(); } } // Insert state to the ICSStateContainer icsStateIndex = this.InsertStateDict(hs.State); afts = this.GetAbstractHierachySync(serverId, hs, icsStateIndex); return afts; case FastTransferStreamType.MessageContent: MessageContent mc = new MessageContent(fs); for (int i = 0; i < mc.PropList.PropValues.Count; i++) { PropValue propValue = mc.PropList.PropValues[i]; if (propValue.PropType == 0x84b0) { CodePage codePage = new CodePage(); codePage.Deserialize(propValue.PropType); this.VerifyCodePageProperty(codePage); } } this.VerifyMarkers(mc); afts = mc.GetAbstractFastTransferStream(); this.VerifyMetaProperty(afts); return afts; case FastTransferStreamType.MessageList: MessageList ml = new MessageList(fs); afts = ml.GetAbstractFastTransferStream(); this.VerifyMetaProperty(afts); this.VerifyMarkers(ml); return afts; case FastTransferStreamType.TopFolder: TopFolder tf = new TopFolder(fs); this.VerifyMarkers(tf); afts = tf.GetAbstractFastTransferStream(); this.VerifyMetaProperty(afts); return afts; default: AdapterHelper.Site.Assert.Fail("The stream type is invalid, its value is:{0}.", this.streamType); return new AbstractFastTransferStream(); } } }
/// <summary> /// Get content sync data. /// </summary> /// <param name="serverID">server id.</param> /// <param name="stateIndex">Start index.</param> /// <param name="cs">Content sync object</param> /// <returns>The AbstractFastTransferStream</returns> public AbstractFastTransferStream GetAbstractContentSync( int serverID, int stateIndex, ContentsSync cs) { AbstractFastTransferStream afts = new AbstractFastTransferStream(); AbstractContentsSync acs = new AbstractContentsSync { AbstractDeletion = new AbstractDeletion { IdSetDeleted = new Modeling.Set<int>() } }; // If the deletion is not null change the AbstractDeletion's field, // else do not change the Deletions field of the AbstractContentsSync if (cs.Deletions != null) { // If the deletion is not null the deletion is present. acs.AbstractDeletion = new AbstractDeletion { IsDeletionPresent = true, IsPidTagIdsetExpiredExist = cs.Deletions.PropList.HasPidTagIdsetExpired, // Check pidtags in the deletions property list. IsPidTagIdsetNoLongerInScopeExist = cs.Deletions.PropList.HasPidTagIdsetNoLongerInScope, IdSetDeleted = new Modeling.Set<int>() }; // Check Idset in the deletion. // If the Idset that can be got from PidTagIdsetDeleted value // in the PropList of the deletions is contained in the objectIdContainer // add it to the IdsetDeleted field in the AbstractDeletion List<ulong> ids = cs.Deletions.IdsetDeleted; foreach (int key in this.objectIdContainer.Keys) { if (ids.Contains(this.objectIdContainer[key])) { acs.AbstractDeletion.IdSetDeleted = acs.AbstractDeletion.IdSetDeleted.Add(key); } } this.VerifyMetaTagIdsetDeletedProperty(this.hasExecuteSynchronizationImportDeletes, this.importDelFlag, ids, this.delObjId); this.hasExecuteSynchronizationImportDeletes = false; } // Whether ProgressTotal is present. acs.IsprogessTotalPresent = cs.ProgressTotal != null; // Whether ReadStateChanges is present. acs.IsReadStateChangesExist = cs.ReadStateChanges != null; acs.MessageInfo = new Modeling.Set<AbstractMessageChangeInfo>(); if (cs.MessageChangeTuples != null) { for (int i = 0; i < cs.MessageChangeTuples.Count; i++) { AbstractMessageChangeInfo info = new AbstractMessageChangeInfo(); Tuple<ProgressPerMessage, MessageChange> msg = cs.MessageChangeTuples[i]; info.IsMessageChangeFull = msg.Item2 is MessageChangeFull; // Whether ProgressPerMessagePresent is present. info.IsProgressPerMessagePresent = msg.Item1 != null; if (msg.Item1 != null) { // If ProgressPerMessagePresent is present, // whether the message followed is a FAI message. info.FollowedFAIMessage = msg.Item1.IsFollowedFAIMessage; } info.IsPidTagChangeNumberExist = msg.Item2.HasPidTagChangeNumber; info.IsPidTagMessageSizeExist = msg.Item2.HasPidTagMessageSize; info.IsPidTagMidExist = msg.Item2.HasPidTagMid; // convert the SourceKey in the messageChangeHeader of the messageChange // to a GID structure, then use this GID to build a LongTermId, // get the id corresponding to the LongTermId,if the id is maintained in the // objectIdContainer,find its index, else set the messageIdIndex of the // AbstractMessageChangeInfo to -1. byte[] buffer = msg.Item2.SourceKey; GID gid = StructureSerializer.Deserialize<GID>(buffer); LongTermId lid = new LongTermId { DatabaseGuid = gid.DatabaseGuid.ToByteArray(), GlobalCounter = gid.GlobalCounter }; ulong id = this.GetIdFromLongTerm(serverID, lid); info.MessageIdIndex = -1; foreach (int k in this.objectIdContainer.Keys) { if (this.objectIdContainer[k] == id) { info.MessageIdIndex = k; break; } } // If messageChangeFull, whether its PropList contains PidTagRtfCompressed. if (msg.Item2 is MessageChangeFull) { info.IsRTFformat = (msg.Item2 as MessageChangeFull).IsRTFFormat; } // Add the AbstractMessageChangeInfo to the MessageInfo of the AbstractContentsSync acs.MessageInfo = acs.MessageInfo.Add(info); } // if there is more than 1 messageChange presents. // whether their order is in descending order. if (cs.MessageChangeTuples.Count > 1) { acs.IsSortByLastModificationTime = true; acs.IsSortByMessageDeliveryTime = true; DateTime prev = cs.MessageChangeTuples[0].Item2.LastModificationTime; for (int i = 1; i < cs.MessageChangeTuples.Count; i++) { DateTime curr = cs.MessageChangeTuples[i].Item2.LastModificationTime; // If one is not in descending order. // set flags to false. if (prev < curr) { acs.IsSortByLastModificationTime = false; acs.IsSortByMessageDeliveryTime = false; break; } } // If the OrderByDeliveryTime flag of the SynchronizationExtraFlag field is not set, there is no requirement on the server to return items in a specific order. if (this.isOrderByDeliveryTimeExtraFlagNotSet) { acs.IsSortByLastModificationTime = false; acs.IsSortByMessageDeliveryTime = false; } } } // Get FinalICSState. acs.FinalICSState = this.GetAbstractState(serverID, stateIndex, cs.State); afts.AbstractContentsSync = acs; afts.StreamType = FastTransferStreamType.contentsSync; afts.AbstractState = new AbstractState(); return afts; }