/// <summary> /// Deserialize items from byte array. /// </summary> /// <param name="byteArray">The byte array which contains response message.</param> /// <param name="currentIndex">The index special where to start.</param> /// <param name="lengthOfItems">The length of items.</param> protected override void DeserializeItemsFromByteArray(byte[] byteArray, ref int currentIndex, int lengthOfItems) { if (lengthOfItems != 0) { throw new ResponseParseErrorException(currentIndex, "ReadAccessResponse over-parse error", null); } int index = currentIndex; this.ReadResponseError = StreamObject.GetCurrent <ResponseError>(byteArray, ref index); currentIndex = index; }
/// <summary> /// Deserialize items from byte array. /// </summary> /// <param name="byteArray">The byte array which contains response message.</param> /// <param name="currentIndex">The index special where to start.</param> /// <param name="lengthOfItems">The length of items.</param> protected override void DeserializeItemsFromByteArray(byte[] byteArray, ref int currentIndex, int lengthOfItems) { int index = currentIndex; if (lengthOfItems != 16) { throw new StreamObjectParseErrorException(currentIndex, "ResponseError", "Stream object over-parse error", null); } byte[] guidarray = new byte[16]; Array.Copy(byteArray, index, guidarray, 0, 16); this.ErrorTypeGUID = new Guid(guidarray); index += 16; switch (this.ErrorTypeGUID.ToString().ToUpper(CultureInfo.CurrentCulture)) { case CellErrorGuid: this.ErrorData = StreamObject.GetCurrent <CellError>(byteArray, ref index); break; case ProtocolErrorGuid: this.ErrorData = StreamObject.GetCurrent <ProtocolError>(byteArray, ref index); break; case Win32ErrorGuid: this.ErrorData = StreamObject.GetCurrent <Win32Error>(byteArray, ref index); break; case HresultErrorGuid: this.ErrorData = StreamObject.GetCurrent <HRESULTError>(byteArray, ref index); break; default: throw new StreamObjectParseErrorException(index - 16, "ResponseError", "Failed to extract the error Guid value, the value" + this.ErrorTypeGUID + "is not defined", null); } ErrorStringSupplementalInfo errorInfo; if (StreamObject.TryGetCurrent <ErrorStringSupplementalInfo>(byteArray, ref index, out errorInfo)) { this.ErrorStringSupplementalInfo = errorInfo; } ResponseError chainedError; if (StreamObject.TryGetCurrent <ResponseError>(byteArray, ref index, out chainedError)) { this.ChainedError = chainedError; } currentIndex = index; }
/// <summary> /// Used to de-serialize the element. /// </summary> /// <param name="byteArray">A Byte array</param> /// <param name="currentIndex">Start position</param> /// <param name="lengthOfItems">The length of the items</param> protected override void DeserializeItemsFromByteArray(byte[] byteArray, ref int currentIndex, int lengthOfItems) { int index = currentIndex; if (lengthOfItems != 0) { throw new StreamObjectParseErrorException(currentIndex, "IntermediateNodeObject", "Stream Object over-parse error", null); } this.Signature = StreamObject.GetCurrent <SignatureObject>(byteArray, ref index); this.DataSize = StreamObject.GetCurrent <DataSizeObject>(byteArray, ref index); currentIndex = index; }
/// <summary> /// This method is used to deserialize the items of the fragment knowledge from the byte array. /// </summary> /// <param name="byteArray">Specify the byte array.</param> /// <param name="currentIndex">Specify the start index from the byte array.</param> /// <param name="lengthOfItems">Specify the current length of items in the fragment knowledge.</param> protected override void DeserializeItemsFromByteArray(byte[] byteArray, ref int currentIndex, int lengthOfItems) { if (lengthOfItems != 0) { throw new KnowledgeParseErrorException(currentIndex, "FragmentKnowledge object over-parse error", null); } int index = currentIndex; FragmentKnowledgeEntry fragmentKnowledgeEntry = null; while (StreamObject.TryGetCurrent <FragmentKnowledgeEntry>(byteArray, ref index, out fragmentKnowledgeEntry)) { this.FragmentKnowledgeEntriesList.Add(fragmentKnowledgeEntry); } currentIndex = index; }
/// <summary> /// This method is used to deserialize the items of the waterline knowledge from the byte array. /// </summary> /// <param name="byteArray">Specify the byte array.</param> /// <param name="currentIndex">Specify the start index from the byte array.</param> /// <param name="lengthOfItems">Specify the current length of items in the waterline knowledge.</param> protected override void DeserializeItemsFromByteArray(byte[] byteArray, ref int currentIndex, int lengthOfItems) { if (lengthOfItems != 0) { throw new KnowledgeParseErrorException(currentIndex, "WaterlineKnowledge object over-parse error", null); } int index = currentIndex; WaterlineKnowledgeEntry waterlineKnowledgeEntry; this.WaterlineKnowledgeData = new List <WaterlineKnowledgeEntry>(); while (StreamObject.TryGetCurrent <WaterlineKnowledgeEntry>(byteArray, ref index, out waterlineKnowledgeEntry)) { this.WaterlineKnowledgeData.Add(waterlineKnowledgeEntry); } currentIndex = index; }
/// <summary> /// This method is used to deserialize the items of the knowledge from the byte array. /// </summary> /// <param name="byteArray">Specify the byte array.</param> /// <param name="currentIndex">Specify the start index from the byte array.</param> /// <param name="lengthOfItems">Specify the current length of items in the knowledge.</param> protected override void DeserializeItemsFromByteArray(byte[] byteArray, ref int currentIndex, int lengthOfItems) { if (lengthOfItems != 0) { throw new KnowledgeParseErrorException(currentIndex, "Knowledge object over-parse error", null); } int index = currentIndex; SpecializedKnowledge specializedKnowledge; this.SpecializedKnowledges = new List <SpecializedKnowledge>(); while (StreamObject.TryGetCurrent <SpecializedKnowledge>(byteArray, ref index, out specializedKnowledge)) { this.SpecializedKnowledges.Add(specializedKnowledge); } currentIndex = index; }
/// <summary> /// This method is used to deserialize the items of the content tag knowledge from the byte array. /// </summary> /// <param name="byteArray">Specify the byte array.</param> /// <param name="currentIndex">Specify the start index from the byte array.</param> /// <param name="lengthOfItems">Specify the current length of items in the content tag knowledge.</param> protected override void DeserializeItemsFromByteArray(byte[] byteArray, ref int currentIndex, int lengthOfItems) { if (lengthOfItems != 0) { throw new KnowledgeParseErrorException(currentIndex, "ContentTagKnowledge object over-parse error", null); } int index = currentIndex; this.ContentTagEntryArray = new List <ContentTagKnowledgeEntry>(); ContentTagKnowledgeEntry outValue; while (StreamObject.TryGetCurrent <ContentTagKnowledgeEntry>(byteArray, ref index, out outValue)) { this.ContentTagEntryArray.Add(outValue); } currentIndex = index; }
/// <summary> /// Deserialize items from byte array. /// </summary> /// <param name="byteArray">The byte array which contains response message.</param> /// <param name="currentIndex">The index special where to start.</param> /// <param name="lengthOfItems">The length of items.</param> protected override void DeserializeItemsFromByteArray(byte[] byteArray, ref int currentIndex, int lengthOfItems) { int index = currentIndex; this.ReassignedSerialNumber = BasicObject.Parse <SerialNumber>(byteArray, ref index); if (index - currentIndex != lengthOfItems) { throw new StreamObjectParseErrorException(currentIndex, "PutChangesResponseSerialNumberReassignAll", "Stream object over-parse error", null); } this.PutChangesResponseSNReassignList = new List <PutChangesResponseSerialNumberReassign>(); PutChangesResponseSerialNumberReassign outValue; while (StreamObject.TryGetCurrent <PutChangesResponseSerialNumberReassign>(byteArray, ref index, out outValue)) { this.PutChangesResponseSNReassignList.Add(outValue); } currentIndex = index; }
/// <summary> /// Used to de-serialize the elements. /// </summary> /// <param name="byteArray">Byte array</param> /// <param name="currentIndex">Start position</param> /// <param name="lengthOfItems">Length of the element</param> protected override void DeserializeItemsFromByteArray(byte[] byteArray, ref int currentIndex, int lengthOfItems) { if (lengthOfItems != 1) { throw new StreamObjectParseErrorException(currentIndex, "DataElementPackage", "Stream object over-parse error", null); } int index = currentIndex; this.Reserved = byteArray[index++]; this.DataElements = new List <DataElement>(); DataElement dataElement; while (StreamObject.TryGetCurrent <DataElement>(byteArray, ref index, out dataElement)) { this.DataElements.Add(dataElement); } currentIndex = index; }
/// <summary> /// Parse stream object from byte array. /// </summary> /// <param name="header">The instance of StreamObjectHeaderStart.</param> /// <param name="byteArray">The byte array.</param> /// <param name="index">The position where to start.</param> /// <returns>The instance of StreamObject.</returns> public static StreamObject ParseStreamObject(StreamObjectHeaderStart header, byte[] byteArray, ref int index) { if (StreamObjectTypeMapping.Keys.Contains(header.Type)) { StreamObject streamObject = Activator.CreateInstance(StreamObjectTypeMapping[header.Type]) as StreamObject; try { index += streamObject.DeserializeFromByteArray(header, byteArray, index); } catch (BasicObjectParseErrorException e) { throw new StreamObjectParseErrorException(index, StreamObjectTypeMapping[header.Type].Name, e); } return(streamObject); } int tmpIndex = index; tmpIndex -= header.HeaderType == StreamObjectHeaderStart.StreamObjectHeaderStart16bit ? 2 : 4; throw new StreamObjectParseErrorException(tmpIndex, "Unknown", string.Format("Failed to create the specified stream object instance, the type {0} of stream object header in the current index is not defined", (int)header.Type), null); }
/// <summary> /// Used to return the length of this element. /// </summary> /// <param name="byteArray">A Byte array</param> /// <param name="startIndex">Start position</param> /// <returns>The length of the element</returns> public override int DeserializeDataElementDataFromByteArray(byte[] byteArray, int startIndex) { int index = startIndex; DataElementHash dataElementHash; if (StreamObject.TryGetCurrent <DataElementHash>(byteArray, ref index, out dataElementHash)) { this.DataElementHash = dataElementHash; } this.ObjectGroupDeclarations = StreamObject.GetCurrent <ObjectGroupDeclarations>(byteArray, ref index); ObjectGroupMetadataDeclarations objectMetadataDeclaration = new ObjectGroupMetadataDeclarations(); if (StreamObject.TryGetCurrent <ObjectGroupMetadataDeclarations>(byteArray, ref index, out objectMetadataDeclaration)) { this.ObjectMetadataDeclaration = objectMetadataDeclaration; } this.ObjectGroupData = StreamObject.GetCurrent <ObjectGroupData>(byteArray, ref index); return(index - startIndex); }
/// <summary> /// Used to de-serialize the data element. /// </summary> /// <param name="byteArray">Byte array</param> /// <param name="startIndex">Start position</param> /// <returns>The length of the element</returns> public override int DeserializeDataElementDataFromByteArray(byte[] byteArray, int startIndex) { int index = startIndex; int headerLength = 0; StreamObjectHeaderStart header; bool isStorageIndexManifestMappingExist = false; while ((headerLength = StreamObjectHeaderStart.TryParse(byteArray, index, out header)) != 0) { index += headerLength; if (header.Type == StreamObjectTypeHeaderStart.StorageIndexManifestMapping) { if (isStorageIndexManifestMappingExist) { throw new DataElementParseErrorException(index - headerLength, "Failed to parse StorageIndexDataElement, only can contain zero or one StorageIndexManifestMapping", null); } this.StorageIndexManifestMapping = StreamObject.ParseStreamObject(header, byteArray, ref index) as StorageIndexManifestMapping; isStorageIndexManifestMappingExist = true; } else if (header.Type == StreamObjectTypeHeaderStart.StorageIndexCellMapping) { this.StorageIndexCellMappingList.Add(StreamObject.ParseStreamObject(header, byteArray, ref index) as StorageIndexCellMapping); } else if (header.Type == StreamObjectTypeHeaderStart.StorageIndexRevisionMapping) { this.StorageIndexRevisionMappingList.Add(StreamObject.ParseStreamObject(header, byteArray, ref index) as StorageIndexRevisionMapping); } else { throw new DataElementParseErrorException(index - headerLength, "Failed to parse StorageIndexDataElement, expect the inner object type StorageIndexCellMapping or StorageIndexRevisionMapping, but actual type value is " + header.Type, null); } } return(index - startIndex); }
/// <summary> /// This method is used to build intermediate node object from an list of object group data element. /// </summary> /// <param name="objectGroupList">Specify the list of object group data elements.</param> /// <param name="dataObj">Specify the object group object.</param> /// <param name="intermediateGuid">Specify the intermediate extended GUID.</param> /// <returns>Return the intermediate node object.</returns> public LeafNodeObject Build(List <ObjectGroupDataElementData> objectGroupList, ObjectGroupObjectData dataObj, ExGuid intermediateGuid) { LeafNodeObject node = null; IntermediateNodeObject rootNode = null; int index = 0; if (StreamObject.TryGetCurrent <LeafNodeObject>(dataObj.Data.Content.ToArray(), ref index, out node)) { if (dataObj.ObjectExGUIDArray == null) { throw new InvalidOperationException("Failed to build intermediate node because the object extend GUID array does not exist."); } node.ExGuid = intermediateGuid; // Contain a single Data Node Object. if (dataObj.ObjectExGUIDArray.Count.DecodedValue == 1u) { ObjectGroupObjectDeclare dataNodeDeclare; ObjectGroupObjectData dataNodeData = this.FindByExGuid(objectGroupList, dataObj.ObjectExGUIDArray.Content[0], out dataNodeDeclare); BinaryItem data = dataNodeData.Data; node.DataNodeObjectData = new DataNodeObjectData(data.Content.ToArray(), 0, (int)data.Length.DecodedValue); node.DataNodeObjectData.ExGuid = dataObj.ObjectExGUIDArray.Content[0]; node.IntermediateNodeObjectList = null; if (SharedContext.Current.IsMsFsshttpRequirementsCaptured) { MsfsshttpdCapture.VerifyObjectGroupObjectDataForDataNodeObject(dataNodeData, dataNodeDeclare, objectGroupList, SharedContext.Current.Site); } } else { // Contain a list of LeafNodeObjectData node.IntermediateNodeObjectList = new List <LeafNodeObject>(); node.DataNodeObjectData = null; foreach (ExGuid extGuid in dataObj.ObjectExGUIDArray.Content) { ObjectGroupObjectDeclare intermediateDeclare; ObjectGroupObjectData intermediateData = this.FindByExGuid(objectGroupList, extGuid, out intermediateDeclare); node.IntermediateNodeObjectList.Add(new IntermediateNodeObjectBuilder().Build(objectGroupList, intermediateData, extGuid)); if (SharedContext.Current.IsMsFsshttpRequirementsCaptured) { MsfsshttpdCapture.VerifyObjectGroupObjectDataForIntermediateNode(intermediateData, intermediateDeclare, objectGroupList, SharedContext.Current.Site); } } } } else if (StreamObject.TryGetCurrent <IntermediateNodeObject>(dataObj.Data.Content.ToArray(), ref index, out rootNode)) { // In Sub chunking for larger than 1MB zip file, MOSS2010 could return IntermediateNodeObject. // For easy further process, the rootNode will be replaced by intermediate node instead. node = new LeafNodeObject(); node.IntermediateNodeObjectList = new List <LeafNodeObject>(); node.DataSize = rootNode.DataSize; node.ExGuid = rootNode.ExGuid; node.Signature = rootNode.Signature; node.DataNodeObjectData = null; foreach (ExGuid extGuid in dataObj.ObjectExGUIDArray.Content) { ObjectGroupObjectDeclare intermediateDeclare; ObjectGroupObjectData intermediateData = this.FindByExGuid(objectGroupList, extGuid, out intermediateDeclare); node.IntermediateNodeObjectList.Add(new IntermediateNodeObjectBuilder().Build(objectGroupList, intermediateData, extGuid)); if (SharedContext.Current.IsMsFsshttpRequirementsCaptured) { MsfsshttpdCapture.VerifyObjectGroupObjectDataForIntermediateNode(intermediateData, intermediateDeclare, objectGroupList, SharedContext.Current.Site); } } } else { throw new InvalidOperationException("In the ObjectGroupDataElement cannot only contain the IntermediateNodeObject or IntermediateNodeOBject."); } return(node); }
/// <summary> /// This method is used to build a root node object from an object group data element list with the specified root extended GUID. /// </summary> /// <param name="objectGroupList">Specify the object group data element list.</param> /// <param name="rootExGuid">Specify the root extended GUID.</param> /// <returns>Return a root node object build from the object group data element list.</returns> private IntermediateNodeObject Build(List <ObjectGroupDataElementData> objectGroupList, ExGuid rootExGuid) { ObjectGroupObjectDeclare rootDeclare; ObjectGroupObjectData root = this.FindByExGuid(objectGroupList, rootExGuid, out rootDeclare); if (SharedContext.Current.IsMsFsshttpRequirementsCaptured) { MsfsshttpdCapture.VerifyObjectCount(root, SharedContext.Current.Site); } int index = 0; IntermediateNodeObject rootNode = null; if (StreamObject.TryGetCurrent <IntermediateNodeObject>(root.Data.Content.ToArray(), ref index, out rootNode)) { rootNode.ExGuid = rootExGuid; foreach (ExGuid extGuid in root.ObjectExGUIDArray.Content) { ObjectGroupObjectDeclare intermediateDeclare; ObjectGroupObjectData intermediateData = this.FindByExGuid(objectGroupList, extGuid, out intermediateDeclare); rootNode.IntermediateNodeObjectList.Add(new LeafNodeObject.IntermediateNodeObjectBuilder().Build(objectGroupList, intermediateData, extGuid)); // Capture the intermediate related requirements if (SharedContext.Current.IsMsFsshttpRequirementsCaptured) { MsfsshttpdCapture.VerifyObjectGroupObjectDataForIntermediateNode(intermediateData, intermediateDeclare, objectGroupList, SharedContext.Current.Site); MsfsshttpdCapture.VerifyLeafNodeObject(rootNode.IntermediateNodeObjectList.Last(), SharedContext.Current.Site); } } if (SharedContext.Current.IsMsFsshttpRequirementsCaptured) { // Capture the root node related requirements. MsfsshttpdCapture.VerifyObjectGroupObjectDataForRootNode(root, rootDeclare, objectGroupList, SharedContext.Current.Site); MsfsshttpdCapture.VerifyIntermediateNodeObject(rootNode, SharedContext.Current.Site); } } else { // If there is only one object in the file, SharePoint Server 2010 does not return the Root Node Object, but an Intermediate Node Object at the beginning. // At this case, we will add the root node object for the further parsing. rootNode = new IntermediateNodeObject(); rootNode.ExGuid = rootExGuid; rootNode.IntermediateNodeObjectList.Add(new LeafNodeObject.IntermediateNodeObjectBuilder().Build(objectGroupList, root, rootExGuid)); rootNode.DataSize = new DataSizeObject(); rootNode.DataSize.DataSize = (ulong)rootNode.IntermediateNodeObjectList.Sum(o => (float)o.DataSize.DataSize); } // Capture all the signature related requirements. if (SharedContext.Current.IsMsFsshttpRequirementsCaptured) { AbstractChunking chunking = ChunkingFactory.CreateChunkingInstance(rootNode); if (chunking != null) { chunking.AnalyzeChunking(rootNode, SharedContext.Current.Site); } } return(rootNode); }
/// <summary> /// Deserialize response from byte array. /// </summary> /// <param name="byteArray">Server returned message.</param> /// <param name="startIndex">The index special where start.</param> /// <returns>The instance of CellResponse.</returns> public static FsshttpbResponse DeserializeResponseFromByteArray(byte[] byteArray, int startIndex) { int index = startIndex; FsshttpbResponse response = new FsshttpbResponse(); response.ProtocolVersion = LittleEndianBitConverter.ToUInt16(byteArray, index); index += 2; response.MinimumVersion = LittleEndianBitConverter.ToUInt16(byteArray, index); index += 2; response.Signature = LittleEndianBitConverter.ToUInt64(byteArray, index); index += 8; int length = 0; StreamObjectHeaderStart streamObjectHeader; if ((length = StreamObjectHeaderStart.TryParse(byteArray, index, out streamObjectHeader)) == 0) { throw new ResponseParseErrorException(index, "Failed to parse the response header", null); } if (!(streamObjectHeader is StreamObjectHeaderStart32bit)) { throw new ResponseParseErrorException(index, "Unexpected 16-bit response stream object header, expect 32-bit stream object header for Response", null); } if (streamObjectHeader.Type != StreamObjectTypeHeaderStart.FsshttpbResponse) { throw new ResponseParseErrorException(index, "Failed to extract the response header type, unexpected value " + streamObjectHeader.Type, null); } if (streamObjectHeader.Length != 1) { throw new ResponseParseErrorException(index, "Response object over-parse error", null); } index += length; response.ResponseStart = streamObjectHeader as StreamObjectHeaderStart32bit; response.Status = (byteArray[index] & 0x1) == 0x1 ? true : false; response.Reserved = (byte)(byteArray[index] >> 1); index += 1; try { if (response.Status) { response.ResponseError = StreamObject.GetCurrent <ResponseError>(byteArray, ref index); response.DataElementPackage = null; response.CellSubResponses = null; } else { DataElementPackage package; if (StreamObject.TryGetCurrent <DataElementPackage>(byteArray, ref index, out package)) { response.DataElementPackage = package; } response.CellSubResponses = new List <FsshttpbSubResponse>(); FsshttpbSubResponse subResponse; while (StreamObject.TryGetCurrent <FsshttpbSubResponse>(byteArray, ref index, out subResponse)) { response.CellSubResponses.Add(subResponse); } } response.ResponseEnd = BasicObject.Parse <StreamObjectHeaderEnd16bit>(byteArray, ref index); } catch (StreamObjectParseErrorException streamObjectException) { throw new ResponseParseErrorException(index, streamObjectException); } catch (DataElementParseErrorException dataElementException) { throw new ResponseParseErrorException(index, dataElementException); } catch (KnowledgeParseErrorException knowledgeException) { throw new ResponseParseErrorException(index, knowledgeException); } if (index != byteArray.Length) { throw new ResponseParseErrorException(index, "Failed to pass the whole response, not reach the end of the byte array", null); } return(response); }