/// <summary> /// Parse the QueryRows request type response body. /// </summary> /// <param name="rawData">The raw data of response</param> /// <returns>The QueryRows request type response body.</returns> public static QueryRowsResponseBody Parse(byte[] rawData) { QueryRowsResponseBody responseBody = new QueryRowsResponseBody(); 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); } 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); index += sizeof(uint); responseBody.RowData = new AddressBookPropertyRow[(uint)responseBody.RowCount]; for (int i = 0; i < responseBody.RowCount; i++) { responseBody.RowData[i] = AddressBookPropertyRow.Parse(rawData, (LargePropertyTagArray)responseBody.Columns, ref index); } } 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> /// This method is used by the client to get a number of rows from the specified Explicit Table. /// </summary> /// <param name="queryRowsRequestBody">The QueryRows request type request body.</param> /// <returns>The response body of QueryRows request type</returns> public QueryRowsResponseBody QueryRows(QueryRowsRequestBody queryRowsRequestBody) { CommonResponse commonResponse = this.SendAddressBookRequest(queryRowsRequestBody, RequestType.QueryRows); QueryRowsResponseBody queryRowsResponseBody = QueryRowsResponseBody.Parse(commonResponse.ResponseBodyRawData); this.VerifyQueryRowsResponseBody(queryRowsResponseBody, queryRowsRequestBody); if (queryRowsResponseBody.HasColumnsAndRows) { foreach (AddressBookPropertyRow row in queryRowsResponseBody.RowData) { this.VerifyAddressBookPropertyRowStructure(row); } this.VerifyLargePropTagArrayStructure(queryRowsResponseBody.Columns.Value); } return(queryRowsResponseBody); }
/// <summary> /// Parse the QueryRows request type response body. /// </summary> /// <param name="rawData">The raw data of response</param> /// <returns>The QueryRows request type response body.</returns> public static QueryRowsResponseBody Parse(byte[] rawData) { QueryRowsResponseBody responseBody = new QueryRowsResponseBody(); 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); } 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); index += sizeof(uint); responseBody.RowData = new AddressBookPropertyRow[(uint)responseBody.RowCount]; for (int i = 0; i < responseBody.RowCount; i++) { responseBody.RowData[i] = AddressBookPropertyRow.Parse(rawData, (LargePropertyTagArray)responseBody.Columns, ref index); } } 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> /// This method is used by the client to get a number of rows from the specified Explicit Table. /// </summary> /// <param name="queryRowsRequestBody">The QueryRows request type request body.</param> /// <returns>The response body of QueryRows request type</returns> public QueryRowsResponseBody QueryRows(QueryRowsRequestBody queryRowsRequestBody) { CommonResponse commonResponse = this.SendAddressBookRequest(queryRowsRequestBody, RequestType.QueryRows); QueryRowsResponseBody queryRowsResponseBody = QueryRowsResponseBody.Parse(commonResponse.ResponseBodyRawData); this.VerifyQueryRowsResponseBody(queryRowsResponseBody, queryRowsRequestBody); if (queryRowsResponseBody.HasColumnsAndRows) { foreach (AddressBookPropertyRow row in queryRowsResponseBody.RowData) { this.VerifyAddressBookPropertyRowStructure(row); if (row.Flag == 0x0) { for (int i = 0; i < row.ValueArray.Length; i++) { if (queryRowsRequestBody.Columns.PropertyTags[i].PropertyType != 0x0000) { this.VerifyAddressBookPropertyValueStructure(row.ValueArray[i]); } } } else { for (int j = 0; j < row.ValueArray.Length; j++) { this.VerifyAddressBookFlaggedPropertyValueStructure((AddressBookFlaggedPropertyValue)row.ValueArray[j]); } } } this.VerifyLargePropertyTagArrayStructure(queryRowsResponseBody.Columns.Value); } return(queryRowsResponseBody); }
/// <summary> /// Verify the QueryRows request type response body related requirements. /// </summary> /// <param name="queryRowsResponseBody">The QueryRowsResponseBody to be verified.</param> /// <param name="queryRowsRequestBody">The QueryRowsRequestBody to be verified.</param> private void VerifyQueryRowsResponseBody(QueryRowsResponseBody queryRowsResponseBody, QueryRowsRequestBody queryRowsRequestBody) { // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMAPIHTTP_R843"); // Verify MS-OXCMAPIHTTP requirement: MS-OXCMAPIHTTP_R843 this.Site.CaptureRequirementIfIsInstanceOfType( queryRowsResponseBody.StatusCode, typeof(uint), 843, @"[In QueryRows 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_R844"); // Verify MS-OXCMAPIHTTP requirement: MS-OXCMAPIHTTP_R844 this.Site.CaptureRequirementIfAreEqual<uint>( 0, queryRowsResponseBody.StatusCode, 844, @"[In QueryRows 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_R845"); // Verify MS-OXCMAPIHTTP requirement: MS-OXCMAPIHTTP_R845 this.Site.CaptureRequirementIfIsInstanceOfType( queryRowsResponseBody.ErrorCode, typeof(uint), 845, @"[In QueryRows 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_R846"); // Verify MS-OXCMAPIHTTP requirement: MS-OXCMAPIHTTP_R846 this.Site.CaptureRequirementIfIsInstanceOfType( queryRowsResponseBody.HasState, typeof(bool), 846, @"[In QueryRows Request Type Success Response Body] HasState (1 byte): A Boolean value that specifies whether the State field is present."); if (queryRowsResponseBody.HasState) { // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMAPIHTTP_R850"); // Verify MS-OXCMAPIHTTP requirement: MS-OXCMAPIHTTP_R850 this.Site.CaptureRequirementIfIsNotNull( queryRowsResponseBody.State, 850, @"[In QueryRows Request Type Success Response Body] [State] This field is present when the HasState field is nonzero."); // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMAPIHTTP_R847"); // Verify MS-OXCMAPIHTTP requirement: MS-OXCMAPIHTTP_R847 this.Site.CaptureRequirementIfIsInstanceOfType( queryRowsResponseBody.State, typeof(STAT), 847, @"[In QueryRows Request Type Success Response Body] State (optional) (36bytes): A STAT structure ([MS-OXNSPI] section 2.3.7) that specifies the state of a specific address book container."); } else { // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMAPIHTTP_R851."); // Verify MS-OXCMAPIHTTP requirement: MS-OXCMAPIHTTP_R851 this.Site.CaptureRequirementIfIsNull( queryRowsResponseBody.State, 851, @"[In QueryRows 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_R852"); // Verify MS-OXCMAPIHTTP requirement: MS-OXCMAPIHTTP_R852 this.Site.CaptureRequirementIfIsInstanceOfType( queryRowsResponseBody.HasColumnsAndRows, typeof(bool), 852, @"[In QueryRows Request Type Success Response Body] HasColumnsAndRows (1 byte): A Boolean value that specifies whether the Columns, RowCount, and RowData fields are present."); if (queryRowsResponseBody.HasColumnsAndRows) { // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMAPIHTTP_R853"); // Verify MS-OXCMAPIHTTP requirement: MS-OXCMAPIHTTP_R853 this.Site.CaptureRequirementIfIsInstanceOfType( queryRowsResponseBody.Columns, typeof(LargePropertyTagArray), 853, @"[In QueryRows Request Type Success Response Body] Columns (optional) (variable): A LargePropTagArray structure (section 2.2.1.3) that specifies the columns for the rows returned."); // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMAPIHTTP_R854."); // Verify MS-OXCMAPIHTTP requirement: MS-OXCMAPIHTTP_R854 this.Site.CaptureRequirementIfIsNotNull( queryRowsResponseBody.Columns, 854, @"[In QueryRows 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_R856."); // Verify MS-OXCMAPIHTTP requirement: MS-OXCMAPIHTTP_R856 this.Site.CaptureRequirementIfIsInstanceOfType( queryRowsResponseBody.RowCount, typeof(uint), 856, @"[In QueryRows 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_R857."); // Verify MS-OXCMAPIHTTP requirement: MS-OXCMAPIHTTP_R857 this.Site.CaptureRequirementIfIsNotNull( queryRowsResponseBody.RowCount, 857, @"[In QueryRows 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_R859"); // Verify MS-OXCMAPIHTTP requirement: MS-OXCMAPIHTTP_R859 this.Site.CaptureRequirementIfIsInstanceOfType( queryRowsResponseBody.RowData, typeof(AddressBookPropertyRow[]), 859, @"[In QueryRows 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 of the Explicit Table."); // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMAPIHTTP_R860."); // Verify MS-OXCMAPIHTTP requirement: MS-OXCMAPIHTTP_R860 this.Site.CaptureRequirementIfIsNotNull( queryRowsResponseBody.RowData, 860, @"[In QueryRows 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_R825, the value of RowCount for queryRowsResponseBody is {0}.", queryRowsResponseBody.RowCount.Value); // Verify MS-OXCMAPIHTTP requirement: MS-OXCMAPIHTTP_R825 // If the row count server maintained is bigger than the requested row number, the server will return the number of rows it maintained, // otherwise, server will return the rows according to the requested row count. this.Site.CaptureRequirementIfIsTrue( queryRowsRequestBody.RowCount >= queryRowsResponseBody.RowCount.Value, 825, @"[In QueryRows 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_R855."); // Verify MS-OXCMAPIHTTP requirement: MS-OXCMAPIHTTP_R855 this.Site.CaptureRequirementIfIsNull( queryRowsResponseBody.Columns, 855, @"[In QueryRows 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_R858."); // Verify MS-OXCMAPIHTTP requirement: MS-OXCMAPIHTTP_R858 this.Site.CaptureRequirementIfIsNull( queryRowsResponseBody.RowCount, 858, @"[In QueryRows 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_R861."); // Verify MS-OXCMAPIHTTP requirement: MS-OXCMAPIHTTP_R861 this.Site.CaptureRequirementIfIsNull( queryRowsResponseBody.RowData, 861, @"[In QueryRows 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_R862"); // Verify MS-OXCMAPIHTTP requirement: MS-OXCMAPIHTTP_R862 this.Site.CaptureRequirementIfIsInstanceOfType( queryRowsResponseBody.AuxiliaryBufferSize, typeof(uint), 862, @"[In QueryRows 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_R863"); // Verify MS-OXCMAPIHTTP requirement: MS-OXCMAPIHTTP_R863 this.Site.CaptureRequirementIfIsInstanceOfType( queryRowsResponseBody.AuxiliaryBuffer, typeof(byte[]), 863, @"[In QueryRows 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_R864"); // Verify MS-OXCMAPIHTTP requirement: MS-OXCMAPIHTTP_R864 this.Site.CaptureRequirementIfAreEqual<uint>( queryRowsResponseBody.AuxiliaryBufferSize, (uint)queryRowsResponseBody.AuxiliaryBuffer.Length, 864, @"[In QueryRows Request Type Success Response Body] [AuxiliaryBuffer] The size of this field, in bytes, is specified by the AuxiliaryBufferSize field."); }