private static Interop.WebSocket.HttpHeader[] MarshalHttpHeaders(IntPtr nativeHeadersPtr, int nativeHeaderCount) { Debug.Assert(nativeHeaderCount >= 0, "'nativeHeaderCount' MUST NOT be negative."); Debug.Assert(nativeHeadersPtr != IntPtr.Zero || nativeHeaderCount == 0, "'nativeHeaderCount' MUST be 0."); Interop.WebSocket.HttpHeader[] httpHeaders = new Interop.WebSocket.HttpHeader[nativeHeaderCount]; // structure of Interop.WebSocket.HttpHeader: // Name = string* // NameLength = uint* // Value = string* // ValueLength = uint* // NOTE - All fields in the object are pointers to the actual value, hence the use of // 4 * IntPtr.Size to get to the next header. int httpHeaderStructSize = 4 * IntPtr.Size; for (int i = 0; i < nativeHeaderCount; i++) { int offset = httpHeaderStructSize * i; IntPtr currentHttpHeaderPtr = IntPtr.Add(nativeHeadersPtr, offset); MarshalAndVerifyHttpHeader(currentHttpHeaderPtr, ref httpHeaders[i]); } Debug.Assert(httpHeaders != null); Debug.Assert(httpHeaders.Length == nativeHeaderCount); return(httpHeaders); }
private static void MarshalAndVerifyHttpHeader(IntPtr httpHeaderPtr, ref Interop.WebSocket.HttpHeader httpHeader) { Debug.Assert(httpHeaderPtr != IntPtr.Zero, "'currentHttpHeaderPtr' MUST NOT be IntPtr.Zero."); IntPtr httpHeaderNamePtr = Marshal.ReadIntPtr(httpHeaderPtr); IntPtr lengthPtr = IntPtr.Add(httpHeaderPtr, IntPtr.Size); int length = Marshal.ReadInt32(lengthPtr); Debug.Assert(length >= 0, "'length' MUST NOT be negative."); if (httpHeaderNamePtr != IntPtr.Zero) { httpHeader.Name = Marshal.PtrToStringAnsi(httpHeaderNamePtr, length); } if ((httpHeader.Name == null && length != 0) || (httpHeader.Name != null && length != httpHeader.Name.Length)) { Debug.Fail("The length of 'httpHeader.Name' MUST MATCH 'length'."); throw new AccessViolationException(); } // structure of Interop.WebSocket.HttpHeader: // Name = string* // NameLength = uint* // Value = string* // ValueLength = uint* // NOTE - All fields in the object are pointers to the actual value, hence the use of // n * IntPtr.Size to get to the correct place in the object. int valueOffset = 2 * IntPtr.Size; int lengthOffset = 3 * IntPtr.Size; IntPtr httpHeaderValuePtr = Marshal.ReadIntPtr(IntPtr.Add(httpHeaderPtr, valueOffset)); lengthPtr = IntPtr.Add(httpHeaderPtr, lengthOffset); length = Marshal.ReadInt32(lengthPtr); httpHeader.Value = Marshal.PtrToStringAnsi(httpHeaderValuePtr, (int)length); if ((httpHeader.Value == null && length != 0) || (httpHeader.Value != null && length != httpHeader.Value.Length)) { Debug.Fail("The length of 'httpHeader.Value' MUST MATCH 'length'."); throw new AccessViolationException(); } }
private static Interop.WebSocket.HttpHeader[] MarshalHttpHeaders(IntPtr nativeHeadersPtr, int nativeHeaderCount) { Debug.Assert(nativeHeaderCount >= 0, "'nativeHeaderCount' MUST NOT be negative."); Debug.Assert(nativeHeadersPtr != IntPtr.Zero || nativeHeaderCount == 0, "'nativeHeaderCount' MUST be 0."); Interop.WebSocket.HttpHeader[] httpHeaders = new Interop.WebSocket.HttpHeader[nativeHeaderCount]; // structure of Interop.WebSocket.HttpHeader: // Name = string* // NameLength = uint* // Value = string* // ValueLength = uint* // NOTE - All fields in the object are pointers to the actual value, hence the use of // 4 * IntPtr.Size to get to the next header. int httpHeaderStructSize = 4 * IntPtr.Size; for (int i = 0; i < nativeHeaderCount; i++) { int offset = httpHeaderStructSize * i; IntPtr currentHttpHeaderPtr = IntPtr.Add(nativeHeadersPtr, offset); MarshalAndVerifyHttpHeader(currentHttpHeaderPtr, ref httpHeaders[i]); } Debug.Assert(httpHeaders != null); Debug.Assert(httpHeaders.Length == nativeHeaderCount); return httpHeaders; }