public T Decode <T>(byte[] buffer, int index, int count, int formatStringOffset, bool force32Bit, int alignment) where T : struct { PicklePtrToStructure converter = delegate(IntPtr ptr) { return(TypeMarshal.ToStruct <T>(ptr, force32Bit, alignment)); }; return((T)Decode(converter, buffer, index, count, formatStringOffset)); }
public object Decode(PicklePtrToStructure converter, byte[] buffer, int index, int count, int formatStringOffset) { if (converter == null) { throw new ArgumentNullException("converter"); } if (buffer == null) { throw new ArgumentNullException("buffer"); } if (index < 0 || index >= buffer.Length) { throw new ArgumentOutOfRangeException("index", "index is out of range"); } if (count < 0 || (index + count) > buffer.Length) { throw new ArgumentOutOfRangeException("count", "count is out of range"); } IntPtr ndrHandle = IntPtr.Zero; IntPtr pObj = IntPtr.Zero; IntPtr pBuf = IntPtr.Zero; try { #region init handle and environment pBuf = Marshal.AllocHGlobal(buffer.Length); Marshal.Copy(buffer, index, pBuf, count); int rt = PickleNativeMethods.MesDecodeBufferHandleCreate(pBuf, (uint)buffer.Length, out ndrHandle); if (rt != PickleError.RPC_S_OK) { throw new PickleException(rt, "Failed to create handle on given buffer."); } if (stubDesc.pHandle != IntPtr.Zero) { Marshal.FreeHGlobal(stubDesc.pHandle); stubDesc.pHandle = IntPtr.Zero; } stubDesc.pHandle = Marshal.AllocHGlobal(Marshal.SizeOf(ndrHandle)); Marshal.WriteIntPtr(stubDesc.pHandle, ndrHandle); #endregion byte[] format = new byte[typeFormatString.Length - formatStringOffset]; Buffer.BlockCopy(typeFormatString, formatStringOffset, format, 0, format.Length); PickleNativeMethods.NdrMesTypeDecode2( ndrHandle, ref __MIDL_TypePicklingInfo, ref stubDesc, format, ref pObj); if (pObj == IntPtr.Zero) { throw new PickleException("Failed to decode on given buffer and formatStringOffset."); } return(converter(pObj)); } finally { if (ndrHandle != IntPtr.Zero) { PickleNativeMethods.MesHandleFree(ndrHandle); //Ignore error } if (stubDesc.pHandle != IntPtr.Zero) { Marshal.FreeHGlobal(stubDesc.pHandle); stubDesc.pHandle = IntPtr.Zero; } if (pObj != IntPtr.Zero) { MIDL_user_free(pObj); pObj = IntPtr.Zero; } if (pBuf != IntPtr.Zero) { Marshal.FreeHGlobal(pBuf); pBuf = IntPtr.Zero; } } }