/// <summary> /// This method is used by the client to get an Explicit Table, in which the rows are determined by the specified criteria. /// </summary> /// <param name="getMatchesRequestBody">The GetMatches request type request body.</param> /// <returns>The response body of the GetMatches request type.</returns> public GetMatchesResponseBody GetMatches(GetMatchesRequestBody getMatchesRequestBody) { CommonResponse commonResponse = this.SendAddressBookRequest(getMatchesRequestBody, RequestType.GetMatches); GetMatchesResponseBody getMatchesResponseBody = GetMatchesResponseBody.Parse(commonResponse.ResponseBodyRawData); this.VerifyGetMatchsResponseBody(getMatchesRequestBody, getMatchesResponseBody); if (getMatchesResponseBody.HasColumnsAndRows) { foreach (AddressBookPropertyRow row in getMatchesResponseBody.RowData) { this.VerifyAddressBookPropertyRowStructure(row); } } return(getMatchesResponseBody); }
/// <summary> /// Parse the GetMatches request type response body. /// </summary> /// <param name="rawData">The raw data of response.</param> /// <returns>The GetMatches request type response body.</returns> public static GetMatchesResponseBody Parse(byte[] rawData) { GetMatchesResponseBody responseBody = new GetMatchesResponseBody(); int index = 0; responseBody.StatusCode = BitConverter.ToUInt32(rawData, index); index += sizeof(uint); responseBody.ErrorCode = BitConverter.ToUInt32(rawData, index); index += sizeof(uint); responseBody.HasState = BitConverter.ToBoolean(rawData, index); index += sizeof(bool); if (responseBody.HasState) { responseBody.State = STAT.Parse(rawData, ref index); } else { responseBody.State = null; } responseBody.HasMinimalIds = BitConverter.ToBoolean(rawData, index); index += sizeof(bool); if (responseBody.HasMinimalIds) { responseBody.MinimalIdCount = BitConverter.ToUInt32(rawData, index); responseBody.MinimalIds = new uint[(uint)responseBody.MinimalIdCount]; index += sizeof(uint); for (int i = 0; i < responseBody.MinimalIdCount; i++) { responseBody.MinimalIds[i] = BitConverter.ToUInt32(rawData, index); index += sizeof(uint); } } else { responseBody.MinimalIdCount = null; responseBody.MinimalIds = null; } responseBody.HasColumnsAndRows = BitConverter.ToBoolean(rawData, index); index += sizeof(bool); if (responseBody.HasColumnsAndRows) { responseBody.Columns = LargePropertyTagArray.Parse(rawData, ref index); responseBody.RowCount = BitConverter.ToUInt32(rawData, index); responseBody.RowData = new AddressBookPropertyRow[(uint)responseBody.RowCount]; index += sizeof(uint); for (int i = 0; i < responseBody.RowCount; i++) { responseBody.RowData[i] = AddressBookPropertyRow.Parse(rawData, (LargePropertyTagArray)responseBody.Columns, ref index); } } else { responseBody.Columns = null; responseBody.RowCount = null; responseBody.RowData = null; } responseBody.AuxiliaryBufferSize = BitConverter.ToUInt32(rawData, index); index += 4; responseBody.AuxiliaryBuffer = new byte[responseBody.AuxiliaryBufferSize]; Array.Copy(rawData, index, responseBody.AuxiliaryBuffer, 0, responseBody.AuxiliaryBufferSize); return(responseBody); }
/// <summary> /// Verify the requirements related to GetMatches request type response body. /// </summary> /// <param name="requesutBody">The request body of GetMatches request type.</param> /// <param name="responseBody">The response body of GetMatches request type.</param> private void VerifyGetMatchsResponseBody(GetMatchesRequestBody requesutBody, GetMatchesResponseBody responseBody) { // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMAPIHTTP_R524"); // Verify MS-OXCMAPIHTTP requirement: MS-OXCMAPIHTTP_R524 this.Site.CaptureRequirementIfIsInstanceOfType( responseBody.StatusCode, typeof(uint), 524, @"[In GetMatches Request Type Success Response Body] StatusCode (4 bytes): An unsigned integer that specifies the status of the request."); // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMAPIHTTP_R525"); // Verify MS-OXCMAPIHTTP requirement: MS-OXCMAPIHTTP_R525 this.Site.CaptureRequirementIfAreEqual<uint>( 0x00000000, responseBody.StatusCode, 525, @"[In GetMatches Request Type Success Response Body] [StatusCode] This field MUST be set to 0x00000000."); // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMAPIHTTP_R526"); // Verify MS-OXCMAPIHTTP requirement: MS-OXCMAPIHTTP_R526 this.Site.CaptureRequirementIfIsInstanceOfType( responseBody.ErrorCode, typeof(uint), 526, @"[In GetMatches Request Type Success Response Body] ErrorCode (4 bytes): An unsigned integer that specifies the return status of the operation."); // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMAPIHTTP_R527"); // Verify MS-OXCMAPIHTTP requirement: MS-OXCMAPIHTTP_R527 this.Site.CaptureRequirementIfIsInstanceOfType( responseBody.HasState, typeof(bool), 527, @"[In GetMatches Request Type Success Response Body] HasState (1 byte): A Boolean value that specifies whether the State field is present."); if (responseBody.HasState) { // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMAPIHTTP_R528"); // Verify MS-OXCMAPIHTTP requirement: MS-OXCMAPIHTTP_R528 this.Site.CaptureRequirementIfIsInstanceOfType( responseBody.State.Value, typeof(STAT), 528, @"[In GetMatches Request Type Success Response Body] State (optional) (36 bytes): A STAT structure ([MS-OXNSPI] section 2.3.7) that specifies the state of a specific address book container."); // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMAPIHTTP_R530"); // Verify MS-OXCMAPIHTTP requirement: MS-OXCMAPIHTTP_R530 // Because the HasState field is true, so if the State has value, then R530 will be verified. this.Site.CaptureRequirementIfIsTrue( responseBody.State.HasValue, 530, @"[In GetMatches Request Type Success Response Body] [State] This field is present when the HasState field is nonzero."); } else { // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMAPIHTTP_R1449"); // Because the HasState field is false, so if the State does not have a value, then R1449 will be verified. this.Site.CaptureRequirementIfIsFalse( responseBody.State.HasValue, 1449, @"[In GetMatches Request Type Success Response Body] [State] This field is not present when the HasState field is zero."); } // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMAPIHTTP_R533"); // Verify MS-OXCMAPIHTTP requirement: MS-OXCMAPIHTTP_R533 this.Site.CaptureRequirementIfIsInstanceOfType( responseBody.HasMinimalIds, typeof(bool), 533, @"[In GetMatches Request Type Success Response Body] HasMinimalIds (1 byte): A Boolean value that specifies whether the MinimalIdCount and MinimalIds fields are present."); if (responseBody.HasMinimalIds) { // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMAPIHTTP_R516"); // Verify MS-OXCMAPIHTTP requirement: MS-OXCMAPIHTTP_R516 this.Site.CaptureRequirementIfIsInstanceOfType( responseBody.MinimalIdCount, typeof(uint), 516, @"[In GetMatches Request Type Success Response Body] The Date type of Field MinimalIdCount is (4 bytes) unsigned integer (optional)."); // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMAPIHTTP_R534"); // Verify MS-OXCMAPIHTTP requirement: MS-OXCMAPIHTTP_R534 this.Site.CaptureRequirementIfAreEqual<uint>( (uint)responseBody.MinimalIds.Length, responseBody.MinimalIdCount.Value, 534, @"[In GetMatches Request Type Success Response Body] MinimalIdCount: An unsigned integer that specifies the number of structures present in the MinimalIds field."); // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMAPIHTTP_R535. The MinimalIdCount is {0}", responseBody.MinimalIdCount.Value); this.Site.CaptureRequirementIfIsTrue( responseBody.MinimalIdCount.HasValue, 535, @"[In GetMatches Request Type Success Response Body] [MinimalIdCount] This field is present when the value of the HasMinimalIds field is nonzero."); // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMAPIHTTP_R538"); // Verify MS-OXCMAPIHTTP requirement: MS-OXCMAPIHTTP_R538 // According to [MS-OXNSPI], the MinimalEntryID is a single DWORD value. // So if MinimalIds is an array of unsigned integer, R538 will be verified. this.Site.CaptureRequirementIfIsInstanceOfType( responseBody.MinimalIds, typeof(uint[]), 538, @"[In GetMatches Request Type Success Response Body] MinimalIds (optional) (variable): An array of MinimalEntryID structures ([MS-OXNSPI] section 2.3.8.1), each of which is the ID of an object found."); // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMAPIHTTP_R539"); // Verify MS-OXCMAPIHTTP requirement: MS-OXCMAPIHTTP_R539 // Because the HasMinimalIds field is true, so if the MinimalIds has value, then R539 will be verified. this.Site.CaptureRequirementIfIsNotNull( responseBody.MinimalIds, 539, @"[In GetMatches Request Type Success Response Body] [MinimalIds] This field is present when the value of the HasMinimalIds field is nonzero."); } else { // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMAPIHTTP_R1450"); // Because the HasMinimalIds field is false, so if the MinimalIdCount does not have a value, then R1450 will be verified. this.Site.CaptureRequirementIfIsFalse( responseBody.MinimalIdCount.HasValue, 1450, @"[In GetMatches Request Type Success Response Body] [MinimalIdCount] This field is not present when the value of the HasMinimalIds field is zero."); // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMAPIHTTP_R1294"); // Verify MS-OXCMAPIHTTP requirement: MS-OXCMAPIHTTP_R1294 // Because the HasMinimalIds field is false, so if the MinimalIds does not have a value, then R1294 will be verified. this.Site.CaptureRequirementIfIsNull( responseBody.MinimalIds, 1294, @"[In GetMatches Request Type Success Response Body] [MinimalIds] This field is not present when the value of the HasMinimalIds field is zero."); } // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMAPIHTTP_R542"); // Verify MS-OXCMAPIHTTP requirement: MS-OXCMAPIHTTP_R542 this.Site.CaptureRequirementIfIsInstanceOfType( responseBody.HasColumnsAndRows, typeof(bool), 542, @"[In GetMatches Request Type Success Response Body] HasColumnsAndRows (1 byte): A Boolean value that specifies whether the Columns, RowCount, and RowData fields are present."); if (responseBody.HasColumnsAndRows) { // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMAPIHTTP_R543"); // Verify MS-OXCMAPIHTTP requirement: MS-OXCMAPIHTTP_R543 this.Site.CaptureRequirementIfIsInstanceOfType( responseBody.Columns.Value, typeof(LargePropertyTagArray), 543, @"[In GetMatches Request Type Success Response Body] Columns (optional) (variable): A LargePropertyTagArray structure (section 2.2.1.3) that specifies the columns used for each row returned."); // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMAPIHTTP_R544"); // Because the HasColumnsAndRows field is true, so if the Columns field has value, then R544 will be verified. this.Site.CaptureRequirementIfIsTrue( responseBody.Columns.HasValue, 544, @"[In GetMatches Request Type Success Response Body] [Columns] This field is present when the value of the HasColumnsAndRows field is nonzero."); // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMAPIHTTP_R547"); // Verify MS-OXCMAPIHTTP requirement: MS-OXCMAPIHTTP_R547 this.Site.CaptureRequirementIfIsInstanceOfType( responseBody.RowCount.Value, typeof(uint), 547, @"[In GetMatches Request Type Success Response Body] RowCount (optional) (4 bytes): An unsigned integer that specifies the number of structures in the RowData field."); // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMAPIHTTP_R545 : the RowCount field is {0}.", responseBody.RowCount.Value); // Because the HasColumnsAndRows field is true, so if the RowCount field has value, then R545 will be verified. this.Site.CaptureRequirementIfIsTrue( responseBody.RowCount.HasValue, 545, @"[In GetMatches Request Type Success Response Body] [RowCount] This field is present when the value of the HasColumnsAndRows field is nonzero."); // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMAPIHTTP_R551"); // Verify MS-OXCMAPIHTTP requirement: MS-OXCMAPIHTTP_R551 this.Site.CaptureRequirementIfIsInstanceOfType( responseBody.RowData, typeof(AddressBookPropertyRow[]), 551, @"[In GetMatches Request Type Success Response Body] RowData (optional) (variable): An array of AddressBookPropertyRow structures (section 2.2.1.2), each of which specifies the row data for the entries requested."); // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMAPIHTTP_R552"); // Verify MS-OXCMAPIHTTP requirement: MS-OXCMAPIHTTP_R552 // Because the HasColumnsAndRows field is true, so if the RowData field has value, then R552 will be verified. this.Site.CaptureRequirementIfIsNotNull( responseBody.RowData, 552, @"[In GetMatches Request Type Success Response Body] [RowData] This field is present when the HasColumnsAndRows field is nonzero."); // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMAPIHTTP_R502 : the RowCount is {0}.", responseBody.RowCount); // Verify MS-OXCMAPIHTTP requirement: MS-OXCMAPIHTTP_R502 // Because the rows count exits on server can smaller than the RowCount value in request. // So if RowCount field in response is less than or equal to the RowCount field in request, R502 will be verified. bool isVerifiedR502 = responseBody.RowCount <= requesutBody.RowCount; this.Site.CaptureRequirementIfIsTrue( isVerifiedR502, 502, @"[In GetMatches Request Type Request Body] RowCount (4 bytes): An unsigned integer that specifies the number of rows the client is requesting."); } else { // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMAPIHTTP_R1451"); // Verify MS-OXCMAPIHTTP requirement: MS-OXCMAPIHTTP_R1451 // Because the HasColumnsAndRows field is false, so if the Columns field does not have value, then R1451 will be verified. this.Site.CaptureRequirementIfIsFalse( responseBody.Columns.HasValue, 1451, @"[In GetMatches Request Type Success Response Body] [Columns] This field is not present when the value of the HasColumnsAndRows field is zero."); // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMAPIHTTP_R548"); // Verify MS-OXCMAPIHTTP requirement: MS-OXCMAPIHTTP_R548 // Because the HasColumnsAndRows field is false, so if the RowCount field does not have value, then R548 will be verified. this.Site.CaptureRequirementIfIsFalse( responseBody.RowCount.HasValue, 548, @"[In GetMatches Request Type Success Response Body] [RowCount] This field is not present when the value of the HasColumnsAndRows field is zero."); // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMAPIHTTP_R1296"); // Verify MS-OXCMAPIHTTP requirement: MS-OXCMAPIHTTP_R1296 // Because the HasColumnsAndRows field is false, so if the RowData field does not have value, then R1296 will be verified. this.Site.CaptureRequirementIfIsNull( responseBody.RowData, 1296, @"[In GetMatches Request Type Success Response Body] [RowData] This field is not present when the HasColumnsAndRows field is zero."); } // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMAPIHTTP_R555"); // Verify MS-OXCMAPIHTTP requirement: MS-OXCMAPIHTTP_R555 this.Site.CaptureRequirementIfIsInstanceOfType( responseBody.AuxiliaryBufferSize, typeof(uint), 555, @"[In GetMatches Request Type Success Response Body] AuxiliaryBufferSize (4 bytes): An unsigned integer that specifies the size, in bytes, of the AuxiliaryBuffer field."); // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMAPIHTTP_R556"); // Verify MS-OXCMAPIHTTP requirement: MS-OXCMAPIHTTP_R556 this.Site.CaptureRequirementIfIsInstanceOfType( responseBody.AuxiliaryBuffer, typeof(byte[]), 556, @"[In GetMatches Request Type Success Response Body] AuxiliaryBuffer (variable): An array of bytes that constitute the auxiliary payload data returned from the server."); // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMAPIHTTP_R557"); // Verify MS-OXCMAPIHTTP requirement: MS-OXCMAPIHTTP_R557 this.Site.CaptureRequirementIfAreEqual<uint>( responseBody.AuxiliaryBufferSize, (uint)responseBody.AuxiliaryBuffer.Length, 557, @"[In GetMatches Request Type Success Response Body] [AuxiliaryBuffer] The size of this field, in bytes, is specified by the AuxiliaryBufferSize field."); }
/// <summary> /// Parse the GetMatches request type response body. /// </summary> /// <param name="rawData">The raw data of response.</param> /// <returns>The GetMatches request type response body.</returns> public static GetMatchesResponseBody Parse(byte[] rawData) { GetMatchesResponseBody responseBody = new GetMatchesResponseBody(); int index = 0; responseBody.StatusCode = BitConverter.ToUInt32(rawData, index); index += sizeof(uint); responseBody.ErrorCode = BitConverter.ToUInt32(rawData, index); index += sizeof(uint); responseBody.HasState = BitConverter.ToBoolean(rawData, index); index += sizeof(bool); if (responseBody.HasState) { responseBody.State = STAT.Parse(rawData, ref index); } else { responseBody.State = null; } responseBody.HasMinimalIds = BitConverter.ToBoolean(rawData, index); index += sizeof(bool); if (responseBody.HasMinimalIds) { responseBody.MinimalIdCount = BitConverter.ToUInt32(rawData, index); responseBody.MinimalIds = new uint[(uint)responseBody.MinimalIdCount]; index += sizeof(uint); for (int i = 0; i < responseBody.MinimalIdCount; i++) { responseBody.MinimalIds[i] = BitConverter.ToUInt32(rawData, index); index += sizeof(uint); } } else { responseBody.MinimalIdCount = null; responseBody.MinimalIds = null; } responseBody.HasColumnsAndRows = BitConverter.ToBoolean(rawData, index); index += sizeof(bool); if (responseBody.HasColumnsAndRows) { responseBody.Columns = LargePropertyTagArray.Parse(rawData, ref index); responseBody.RowCount = BitConverter.ToUInt32(rawData, index); responseBody.RowData = new AddressBookPropertyRow[(uint)responseBody.RowCount]; index += sizeof(uint); for (int i = 0; i < responseBody.RowCount; i++) { responseBody.RowData[i] = AddressBookPropertyRow.Parse(rawData, (LargePropertyTagArray)responseBody.Columns, ref index); } } else { responseBody.Columns = null; responseBody.RowCount = null; responseBody.RowData = null; } responseBody.AuxiliaryBufferSize = BitConverter.ToUInt32(rawData, index); index += 4; responseBody.AuxiliaryBuffer = new byte[responseBody.AuxiliaryBufferSize]; Array.Copy(rawData, index, responseBody.AuxiliaryBuffer, 0, responseBody.AuxiliaryBufferSize); return responseBody; }