/// <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> /// Gets AbstractState structure. /// </summary> /// <param name="serverID">an int value,represents the id of a server</param> /// <param name="astateIndex">the index of a ICSStateData maintained /// in the state dictionary(ICSStateContainer)</param> /// <param name="s">A state object.</param> /// <returns>The AbstractState corresponding to the state object.</returns> private AbstractState GetAbstractState( int serverID, int astateIndex, State s) { AbstractState astate = new AbstractState(); // If CnsetRead which represents a list of change numbers contains in the state, // check whether the CnsetRead is newer than those contained in the dictionary _CnsetRead // if the CnsetRead is newer, add the CnsetRead to the dictionary _CnsetRead if (s.CnsetRead != null) { astate.IsNewCnsetReadPropertyChangeNumber = !this.IsInDict(s.CnsetRead, this.cnsetRead); if (astate.IsNewCnsetReadPropertyChangeNumber) { this.cnsetRead.Add(AdapterHelper.GetCnsetReadIndex(), s.CnsetRead); } } // If CnsetSeen which represents a list of change numbers contains in the state, // check whether the CnsetSeen is newer than those contained in the dictionary _CnsetSeen // if the CnsetSeen is newer, add the CnsetSeen to the dictionary _CnsetSeen if (s.CnsetSeen != null) { astate.IsNewCnsetSeenPropertyChangeNumber = !this.IsInDict(s.CnsetSeen, this.cnsetSeen); // After the read state modified, the CN will not be changed in server 2007 and 2013. if (!astate.IsNewCnsetSeenPropertyChangeNumber) { if (Common.IsRequirementEnabled(2246, this.Site)) { if (this.cnsetSeen.Values.Count != 0) { astate.IsNewCnsetSeenPropertyChangeNumber = this.HasSameCnset(s.CnsetSeen, this.cnsetSeen); } } } if (astate.IsNewCnsetSeenPropertyChangeNumber) { this.cnsetSeen.Add(AdapterHelper.GetCnsetSeenIndex(), s.CnsetSeen); } } // If CnsetSeenFAI which represents a list of change numbers contains in the state, // check whether the CnsetSeenFAI is newer than those contained in the dictionary _CnsetSeenFAI // If the CnsetSeenFAI is newer, add the CnsetSeenFAI to the dictionary _CnsetSeenFAI if (s.CnsetSeenFAI != null) { astate.IsNewCnsetSeenFAIPropertyChangeNumber = !this.IsInDict(s.CnsetSeenFAI, this.cnsetSeenFAI); if (astate.IsNewCnsetSeenFAIPropertyChangeNumber) { this.cnsetSeenFAI.Add(AdapterHelper.GetCnsetSeenFAIIndex(), s.CnsetSeenFAI); } } // If IdsetGiven which convert to a list of LongTermIds is not empty, // convert each LongTermId in the list of LongTermIds to message id, // and if the id is not contained in the objectIdContainer add the id // to the IdSetGiven of the AbstractState. astate.IdSetGiven = new Set<int>(); if (s.IdsetGiven != null) { List<LongTermId> lids = s.IdsetGiven.GetLongTermIds(); List<ulong> ids = new List<ulong>(); for (int i = 0; i < lids.Count; i++) { ids.Add(this.GetIdFromLongTerm(serverID, lids[i])); } foreach (int key in this.objectIdContainer.Keys) { if (ids.Contains(this.objectIdContainer[key])) { astate.IdSetGiven = astate.IdSetGiven.Add(key); } } } // astateIndex is an incoming parameter. // Set the AbstractICSStateIndex of the AbstractICSState. astate.AbstractICSStateIndex = astateIndex; return astate; }
/// <summary> /// Deserialize fields from a FastTransferStream. /// </summary> /// <param name="stream">A FastTransferStream.</param> public override void Deserialize(FastTransferStream stream) { this.messageChangeTuples = new List<Tuple<ProgressPerMessage, MessageChange>>(); if (ProgressTotal.Verify(stream)) { this.progressTotal = new ProgressTotal(stream); } while (ProgressPerMessage.Verify(stream) || MessageChange.Verify(stream)) { ProgressPerMessage tmp1 = null; MessageChange tmp2 = null; if (ProgressPerMessage.Verify(stream)) { tmp1 = new ProgressPerMessage(stream); } tmp2 = MessageChange.DeserializeFrom(stream) as MessageChange; this.messageChangeTuples.Add( new Tuple<ProgressPerMessage, MessageChange>( tmp1, tmp2)); } if (Deletions.Verify(stream)) { this.deletions = new Deletions(stream); } if (ReadStateChanges.Verify(stream)) { this.readStateChanges = new ReadStateChanges(stream); } this.state = new State(stream); if (!stream.ReadMarker(Markers.PidTagIncrSyncEnd)) { AdapterHelper.Site.Assert.Fail("The stream cannot be deserialized successfully."); } }
/// <summary> /// Insert state value into state dictionary. /// </summary> /// <param name="s">State object.</param> /// <returns>State value index in container.</returns> private int InsertStateDict(State s) { if (s != null && s.PropList != null && s.PropList.PropValues != null && s.PropList.PropValues.Count > 0) { int index = AdapterHelper.GetICSStateIndex(); ICSStateData data = new ICSStateData(); for (int i = 0; i < s.PropList.PropValues.Count; i++) { PropValue value = s.PropList.PropValues[i]; VarPropTypePropValue varPropTypePropValue = value as VarPropTypePropValue; AdapterHelper.Site.Assert.IsNotNull(varPropTypePropValue, "The VarPropTypePropValue should not be null."); if (value.PropType == 0x0102 && varPropTypePropValue.PropInfo.PropID == 0x67D2) { // PidTagCnsetRead data.PidTagCnsetRead = varPropTypePropValue.ValueArray; } else if (value.PropType == 0x0102 && varPropTypePropValue.PropInfo.PropID == 0x6796) { // PidTagCnsetSeen data.PidTagCnsetSeen = varPropTypePropValue.ValueArray; } else if (value.PropType == 0x0102 && varPropTypePropValue.PropInfo.PropID == 0x67DA) { // PidTagCnsetSeenFAI data.PidTagCnsetSeenFAI = varPropTypePropValue.ValueArray; } else if (value.PropType == 0x003 && varPropTypePropValue.PropInfo.PropID == 0x4017) { // PidTagIdsetGiven data.PidTagIdsetGiven = varPropTypePropValue.ValueArray; } else { AdapterHelper.Site.Assert.Fail("Invalid property, its ID is {0} and type is {1}.", value.PropInfo.PropID.ToString("X4"), value.PropType.ToString("X4")); } } this.icsStateContainer.Add(index, data); return index; } else { AdapterHelper.Site.Assert.Fail("Invalid input state, ensure the state not null and have more than one PropValue in its PropList."); return -1; } }
/// <summary> /// Deserialize fields from a FastTransferStream. /// </summary> /// <param name="stream">A FastTransferStream.</param> public override void Deserialize(FastTransferStream stream) { this.folderChangeList = new List<FolderChange>(); while (FolderChange.Verify(stream)) { this.folderChangeList.Add(new FolderChange(stream)); } if (Deletions.Verify(stream)) { this.deletions = new Deletions(stream); } this.state = new State(stream); if (!stream.ReadMarker(Markers.PidTagIncrSyncEnd)) { AdapterHelper.Site.Assert.Fail("The stream cannot be deserialized successfully."); } }