/// <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) { if (lengthOfItems != 8) { throw new StreamObjectParseErrorException(currentIndex, "DataSize", "Stream Object over-parse error", null); } this.DataSize = LittleEndianBitConverter.ToUInt64(byteArray, currentIndex); currentIndex += 8; }
/// <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 != 4) { throw new StreamObjectParseErrorException(currentIndex, "HRESULTError", "Stream object over-parse error", null); } this.ErrorCode = LittleEndianBitConverter.ToInt32(byteArray, currentIndex); currentIndex += 4; }
/// <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 != 4) { throw new StreamObjectParseErrorException(currentIndex, "ProtocolError", "Stream object over-parse error", null); } this.ErrorCode = (ProtocolErrorCode)LittleEndianBitConverter.ToInt32(byteArray, currentIndex); if (!Enum.IsDefined(typeof(ProtocolErrorCode), this.ErrorCode)) { throw new StreamObjectParseErrorException(currentIndex, "ProtocolError", "Unexpected error code value " + this.ErrorCode, null); } currentIndex += 4; }
/// <summary> /// Append a specified Init32 type value into the buffer with the specified bit length. /// </summary> /// <param name="value">Specify the value which needs to be appended.</param> /// <param name="length">Specify the bit length which the value will occupy in the buffer.</param> public void AppendInit32(int value, int length) { byte[] convertedBytes = LittleEndianBitConverter.GetBytes(value); this.SetBytes(convertedBytes, length); }
/// <summary> /// Append a specified Unit64 type value into the buffer with the specified bit length. /// </summary> /// <param name="value">Specify the value which needs to be appended.</param> /// <param name="length">Specify the bit length which the value will occupy in the buffer.</param> public void AppendUInt64(ulong value, int length) { byte[] convertedBytes = LittleEndianBitConverter.GetBytes(value); this.SetBytes(convertedBytes, length); }
/// <summary> /// Read specified bit length content as an Int32 type and increase the bit offset with the specified length. /// </summary> /// <param name="readingLength">Specify the reading bit length.</param> /// <returns>Return the Int32 type value.</returns> public int ReadInt32(int readingLength) { byte[] uint32Bytes = this.GetBytes(readingLength, 4); return(LittleEndianBitConverter.ToInt32(uint32Bytes, 0)); }
/// <summary> /// Read specified bit length content as an UInt16 type and increase the bit offset with the specified length. /// </summary> /// <param name="readingLength">Specify the reading bit length.</param> /// <returns>Return the UInt16 value.</returns> public short ReadInt16(int readingLength) { byte[] uint16Bytes = this.GetBytes(readingLength, 2); return(LittleEndianBitConverter.ToInt16(uint16Bytes, 0)); }
/// <summary> /// Read specified bit length content as an UInt64 type and increase the bit offset. /// </summary> /// <param name="readingLength">Specify the reading bit length.</param> /// <returns>Return the UInt64 type value.</returns> public ulong ReadUInt64(int readingLength) { byte[] uint64Bytes = this.GetBytes(readingLength, 8); return(LittleEndianBitConverter.ToUInt64(uint64Bytes, 0)); }
/// <summary> /// This method is used to convert the element into a byte List /// </summary> /// <returns>Return the Byte List</returns> public List <byte> SerializeToByteList() { this.RequestStart = new StreamObjectHeaderStart32bit(StreamObjectTypeHeaderStart.Request, 0); this.UserAgentStart = new StreamObjectHeaderStart32bit(StreamObjectTypeHeaderStart.UserAgent, 0); this.UserAgentGUID = new StreamObjectHeaderStart32bit(StreamObjectTypeHeaderStart.UserAgentGUID, 16); this.UserAgentVersion = new StreamObjectHeaderStart32bit(StreamObjectTypeHeaderStart.UserAgentversion, 4); this.UserAgentEnd = new StreamObjectHeaderEnd16bit((int)StreamObjectTypeHeaderEnd.UserAgent); this.CellRequestEnd = new StreamObjectHeaderEnd16bit((int)StreamObjectTypeHeaderEnd.Request); List <byte> byteList = new List <byte>(); // Protocol Version byteList.AddRange(LittleEndianBitConverter.GetBytes(this.ProtocolVersion)); // Minimum Version byteList.AddRange(LittleEndianBitConverter.GetBytes(this.MinimumVersion)); // Signature byteList.AddRange(LittleEndianBitConverter.GetBytes(this.Signature)); // Request Start byteList.AddRange(this.RequestStart.SerializeToByteList()); // User Agent Start byteList.AddRange(this.UserAgentStart.SerializeToByteList()); // User Agent GUID byteList.AddRange(this.UserAgentGUID.SerializeToByteList()); // GUID byteList.AddRange(this.GUID.ToByteArray()); // User Agent Version byteList.AddRange(this.UserAgentVersion.SerializeToByteList()); // Version byteList.AddRange(LittleEndianBitConverter.GetBytes(this.Version)); // User Agent End byteList.AddRange(this.UserAgentEnd.SerializeToByteList()); if (this.IsRequestHashingOptionsUsed) { List <byte> hashSchemaList = this.RequestHashingSchema.SerializeToByteList(); this.RequestHashingOptionsDeclaration = new StreamObjectHeaderStart32bit(StreamObjectTypeHeaderStart.RequestHashOptions, hashSchemaList.Count + 1); // Request Hashing Options Declaration byteList.AddRange(this.RequestHashingOptionsDeclaration.SerializeToByteList()); // Request Hashing Schema byteList.AddRange(hashSchemaList); // Reserve BitWriter bw = new BitWriter(1); bw.AppendInit32(this.Reserve1, 1); bw.AppendInit32(this.Reserve2, 1); bw.AppendInit32(this.RequestDataElementHashesInsteadofData, 1); bw.AppendInit32(this.RequestDataElementHashes, 1); bw.AppendInit32(this.Reserve3, 4); byteList.AddRange(bw.Bytes); } // Sub-requests if (this.SubRequests != null && this.SubRequests.Count != 0) { foreach (FsshttpbCellSubRequest subRequest in this.SubRequests) { byteList.AddRange(subRequest.SerializeToByteList()); } } else { throw new InvalidOperationException("MUST contain sub request in request structure which is defined in the MS-FSSHTTPB."); } // Data Element Package if (this.DataElementPackage != null) { byteList.AddRange(this.DataElementPackage.SerializeToByteList()); } // Cell Request End byteList.AddRange(this.CellRequestEnd.SerializeToByteList()); return(byteList); }
/// <summary> /// Used to convert the element into a byte List. /// </summary> /// <param name="byteList">A Byte list</param> /// <returns>A constant value 8</returns> protected override int SerializeItemsToByteList(List <byte> byteList) { byteList.AddRange(LittleEndianBitConverter.GetBytes(this.DataSize)); return(8); }
/// <summary> /// This method is used to get the byte value of the 16-bit stream object header End. /// </summary> /// <returns>Return StreamObjectHeaderEnd8bit value represented by unsigned short integer.</returns> public ushort ToUint16() { List <byte> bytes = this.SerializeToByteList(); return(LittleEndianBitConverter.ToUInt16(bytes.ToArray(), 0)); }
/// <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); }
/// <summary> /// This method is used to verify the intermediate node related requirements. /// </summary> /// <param name="instance">Specify the intermediate node instance.</param> /// <param name="site">Specify the ITestSite instance.</param> public void VerifyIntermediateNodeObject(IntermediateNodeObject instance, ITestSite site) { // If the instance is not null and there are no parsing errors, then the IntermediateNodeObject related adapter requirements can be directly captured. if (null == instance) { site.Assert.Fail("The instance of type IntermediateNodeObject is null due to parsing error or type casting error."); } // Verify the stream object header related requirements. this.ExpectStreamObjectHeaderStart(instance.StreamObjectHeaderStart, instance.GetType(), site); // Verify MS-FSSHTTPD requirement: MS-FSSHTTPD_R55 site.CaptureRequirementIfAreEqual <Type>( typeof(StreamObjectHeaderStart16bit), instance.StreamObjectHeaderStart.GetType(), "MS-FSSHTTPD", 55, @"[In Intermediate Node Object Data] Intermediate Node Start (2 bytes): A 16-bit stream object header, as specified in [MS-FSSHTTPB] section 2.2.1.5.1, with a Header Type of 0x00, Compound of 0x1, Type of 0x1F, and Length of 0x00."); // Verify MS-FSSHTTPD requirement: MS-FSSHTTPD_R56 site.CaptureRequirementIfAreEqual <ushort>( 0xFC, LittleEndianBitConverter.ToUInt16(instance.StreamObjectHeaderStart.SerializeToByteList().ToArray(), 0), "MS-FSSHTTPD", 56, @"[In Intermediate Node Object Data] Intermediate Node Start (2 bytes): The value of this field[Intermediate Node Start] MUST be 0x00FC."); // Verify MS-FSSHTTPD requirement: MS-FSSHTTPD_R57 site.CaptureRequirementIfAreEqual <Type>( typeof(StreamObjectHeaderStart16bit), instance.Signature.StreamObjectHeaderStart.GetType(), "MS-FSSHTTPD", 57, @"[In Intermediate Node Object Data] Signature Header (2 bytes): A 16-bit stream object header, as specified in [MS-FSSHTTPB] section 2.2.1.5.1, with a Header Type of 0x00, Compound of 0x0, Type of 0x21, and Length equal to the size of Signature Data."); // Verify MS-FSSHTTPD requirement: MS-FSSHTTPD_R61 site.CaptureRequirementIfAreEqual <Type>( typeof(StreamObjectHeaderStart16bit), instance.DataSize.StreamObjectHeaderStart.GetType(), "MS-FSSHTTPD", 61, @"[In Intermediate Node Object Data] Data Size Header (2 bytes): A 16-bit stream object header, as specified in [MS-FSSHTTPB] section 2.2.1.5.1, with a Header Type of 0x00, Compound of 0x0, Type of 0x22, and Length of 0x08 (the size, in bytes, of Data Size)."); // Verify MS-FSSHTTPD requirement: MS-FSSHTTPD_R8013 site.CaptureRequirementIfAreEqual <uint>( 0x1110, LittleEndianBitConverter.ToUInt16(instance.DataSize.StreamObjectHeaderStart.SerializeToByteList().ToArray(), 0), "MS-FSSHTTPD", 8013, @"[In Intermediate Node Object Data] Data Size Header (2 bytes): The value of this field[Data Size Header] MUST be 0x1110."); // Verify the stream object header end related requirements. this.ExpectStreamObjectHeaderEnd(instance.StreamObjectHeaderEnd, instance.GetType(), site); this.ExpectCompoundObject(instance.StreamObjectHeaderStart, site); // Verify MS-FSSHTTPD requirement: MS-FSSHTTPD_R63 site.CaptureRequirementIfAreEqual <Type>( typeof(StreamObjectHeaderEnd8bit), instance.StreamObjectHeaderEnd.GetType(), "MS-FSSHTTPD", 63, @"[In Intermediate Node Object Data] Intermediate Node End (1 byte): An 8-bit stream object header end, as specified in [MS-FSSHTTPB] section 2.2.1.5.3, that specifies a stream object of type 0x1F."); // Verify MS-FSSHTTPD requirement: MS-FSSHTTPD_R8014 site.CaptureRequirementIfAreEqual <byte>( 0x7D, instance.StreamObjectHeaderEnd.SerializeToByteList()[0], "MS-FSSHTTPD", 8014, @"[In Intermediate Node Object Data] Intermediate Node End (1 byte):The value of this field[Intermediate Node End] MUST be 0x7D."); }
/// <summary> /// This method is used to verify the root node related requirements. /// </summary> /// <param name="instance">Specify the intermediate node instance.</param> /// <param name="site">Specify the ITestSite instance.</param> public void VerifyRootNodeObject(RootNodeObject instance, ITestSite site) { // If the instance is not null and there are no parsing errors, then the RootNodeObject related adapter requirements can be directly captured. if (null == instance) { site.Assert.Fail("The instance of type RootNodeObject is null due to parsing error or type casting error."); } // Verify the stream object header related requirements. this.ExpectStreamObjectHeaderStart(instance.StreamObjectHeaderStart, instance.GetType(), site); // Capture requirement MS-FSSHTTPD_R37, if stream object start type is StreamObjectHeaderStart32bit. site.CaptureRequirement( "MS-FSSHTTPD", 37, @"[In Root Node Object Data] Root Node Start (2 bytes): A 16-bit stream object header, as specified in [MS-FSSHTTPB] section 2.2.1.5.1, with a Header Type of 0x00, Compound of 0x1, Type of 0x20, and Length of 0x00."); // Verify MS-FSSHTTPD requirement: MS-FSSHTTPD_R38 site.CaptureRequirementIfAreEqual <ushort>( 0x104, LittleEndianBitConverter.ToUInt16(instance.StreamObjectHeaderStart.SerializeToByteList().ToArray(), 0), "MS-FSSHTTPD", 38, @"[In Root Node Object Data] Root Node Start (2 bytes): The value of this field[Root Node Start] MUST be 0x0104."); // Directly capture requirement MS-FSSHTTPD_R38, if all above asserts pass. site.CaptureRequirementIfAreEqual <Type>( typeof(StreamObjectHeaderStart16bit), instance.DataSize.StreamObjectHeaderStart.GetType(), "MS-FSSHTTPD", 43, @"[In Root Node Object Data] Data Size Header (2 bytes): A 16-bit stream object header, as specified in [MS-FSSHTTPB] section 2.2.1.5.1, with a Header Type of 0x00, Compound of 0x0, Type of 0x22, and Length of 0x08 (the size, in bytes, of Data Size)."); // Verify MS-FSSHTTPD requirement: MS-FSSHTTPD_R8010 site.CaptureRequirementIfAreEqual <uint>( 0x1110, LittleEndianBitConverter.ToUInt16(instance.DataSize.StreamObjectHeaderStart.SerializeToByteList().ToArray(), 0), "MS-FSSHTTPD", 8010, @"[In Root Node Object Data] Data Size Header (2 bytes): The value of this field[Data Size Header] MUST be 0x1110."); // Verify MS-FSSHTTPD requirement: MS-FSSHTTPD_R39 site.CaptureRequirementIfAreEqual <Type>( typeof(StreamObjectHeaderStart16bit), instance.Signature.StreamObjectHeaderStart.GetType(), "MS-FSSHTTPD", 39, @"[In Root Node Object Data] Signature Header (2 bytes): A 16-bit stream object header, as specified in [MS-FSSHTTPB] section 2.2.1.5.1, with a Header Type of 0x00, Compound of 0x0, Type of 0x21, and Length equal to the size of Signature Data."); // Verify the stream object header end related requirements. this.ExpectStreamObjectHeaderEnd(instance.StreamObjectHeaderEnd, instance.GetType(), site); this.ExpectCompoundObject(instance.StreamObjectHeaderStart, site); // Verify MS-FSSHTTPD requirement: MS-FSSHTTPD_R45 site.CaptureRequirementIfAreEqual <Type>( typeof(StreamObjectHeaderEnd8bit), instance.StreamObjectHeaderEnd.GetType(), "MS-FSSHTTPD", 45, @"[In Root Node Object Data] Root Node End (1 byte): An 8-bit stream object header end, as specified in [MS-FSSHTTPB] section 2.2.1.5.3, that specifies a stream object of type 0x20."); // Verify MS-FSSHTTPD requirement: MS-FSSHTTPD_R46 site.CaptureRequirementIfAreEqual <byte>( 0x81, instance.StreamObjectHeaderEnd.SerializeToByteList()[0], "MS-FSSHTTPD", 46, @"[In Root Node Object Data] Root Node End (1 byte): The value of this field[Root Node End] MUST be 0x81."); }
/// <summary> /// This method is used to verify the leaf node related requirements. /// </summary> /// <param name="instance">Specify the leaf node instance.</param> /// <param name="site">Specify the ITestSite instance.</param> public void VerifyLeafNodeObject(LeafNodeObject instance, ITestSite site) { // If the instance is not null and there are no parsing errors, then the LeafNodeObjectData related adapter requirements can be directly captured. if (null == instance) { site.Assert.Fail("The instance of type LeafNodeObjectData is null due to parsing error or type casting error."); } // Verify the stream object header related requirements. this.ExpectStreamObjectHeaderStart(instance.StreamObjectHeaderStart, instance.GetType(), site); // Verify MS-FSSHTTPD requirement: MS-FSSHTTPD_R55 site.CaptureRequirementIfAreEqual <Type>( typeof(StreamObjectHeaderStart16bit), instance.StreamObjectHeaderStart.GetType(), "MS-FSSHTTPD", 55, @"[In Leaf Node Object Data] Leaf Node Start (2 bytes): A 16-bit stream object header, as specified in [MS-FSSHTTPB] section 2.2.1.5.1, with a Header Type of 0x00, Compound of 0x1, Type of 0x1F, and Length of 0x00."); // Verify MS-FSSHTTPD requirement: MS-FSSHTTPD_R56 site.CaptureRequirementIfAreEqual <ushort>( 0xFC, LittleEndianBitConverter.ToUInt16(instance.StreamObjectHeaderStart.SerializeToByteList().ToArray(), 0), "MS-FSSHTTPD", 56, @"[In Leaf Node Object Data] Leaf Node Start (2 bytes): The value of this field[Leaf Node Start] MUST be 0x00FC."); // Verify MS-FSSHTTPD requirement: MS-FSSHTTPD_R57 site.CaptureRequirementIfAreEqual <Type>( typeof(StreamObjectHeaderStart16bit), instance.Signature.StreamObjectHeaderStart.GetType(), "MS-FSSHTTPD", 57, @"[In Leaf Node Object Data] Signature Header (2 bytes): A 16-bit stream object header, as specified in [MS-FSSHTTPB] section 2.2.1.5.1, with a Header Type of 0x00, Compound of 0x0, Type of 0x21, and Length equal to the size of Signature Data."); // Verify MS-FSSHTTPD requirement: MS-FSSHTTPD_R61 site.CaptureRequirementIfAreEqual <Type>( typeof(StreamObjectHeaderStart16bit), instance.DataSize.StreamObjectHeaderStart.GetType(), "MS-FSSHTTPD", 61, @"[In Leaf Node Object Data] Data Size Header (2 bytes): A 16-bit stream object header, as specified in [MS-FSSHTTPB] section 2.2.1.5.1, with a Header Type of 0x00, Compound of 0x0, Type of 0x22, and Length of 0x08 (the size, in bytes, of Data Size)."); // Verify MS-FSSHTTPD requirement: MS-FSSHTTPD_R8013 site.CaptureRequirementIfAreEqual <uint>( 0x1110, LittleEndianBitConverter.ToUInt16(instance.DataSize.StreamObjectHeaderStart.SerializeToByteList().ToArray(), 0), "MS-FSSHTTPD", 8013, @"[In Leaf Node Object Data] Data Size Header (2 bytes): The value of this field[Data Size Header] MUST be 0x1110."); // Verify MS-FSSHTTPD requirement: MS-FSSHTTPD_R1360 if (Common.IsRequirementEnabled("MS-FSSHTTP-FSSHTTPB", 1360, site)) { if (instance.DataHash != null) { site.CaptureRequirementIfAreEqual <Type>( typeof(StreamObjectHeaderStart16bit), instance.DataHash.StreamObjectHeaderStart.GetType(), "MS-FSSHTTPD", 1360, @"[In Appendix A: Product Behavior]Implementation does support the Data Hash Header(SharePoint Server 2016 and above follow this behavior.)"); site.CaptureRequirementIfAreEqual <Type>( typeof(BinaryItem), instance.DataHash.Data.GetType(), "MS-FSSHTTPD", 202, @"[In Leaf Node Object Data]Data Hash (variable): A binary item, as specified in [MS-FSSHTTPB] section 2.2.1.3, that specifies the data hash."); } } // Verify the stream object header end related requirements. this.ExpectStreamObjectHeaderEnd(instance.StreamObjectHeaderEnd, instance.GetType(), site); this.ExpectCompoundObject(instance.StreamObjectHeaderStart, site); if (instance.StreamObjectHeaderEnd != null) { // Verify MS-FSSHTTPD requirement: MS-FSSHTTPD_R63 site.CaptureRequirementIfAreEqual <Type>( typeof(StreamObjectHeaderEnd8bit), instance.StreamObjectHeaderEnd.GetType(), "MS-FSSHTTPD", 63, @"[In Leaf Node Object Data] Leaf Node End (1 byte): An 8-bit stream object header end, as specified in [MS-FSSHTTPB] section 2.2.1.5.3, that specifies a stream object of type 0x1F."); // Verify MS-FSSHTTPD requirement: MS-FSSHTTPD_R8014 site.CaptureRequirementIfAreEqual <byte>( 0x7D, instance.StreamObjectHeaderEnd.SerializeToByteList()[0], "MS-FSSHTTPD", 8014, @"[In Leaf Node Object Data] Leaf Node End (1 byte):The value of this field[Leaf Node End] MUST be 0x7D."); } }