public void WriteTest() { using (var m = new SafeHGlobalHandle(10)) using (var ms = new MarshalingStream((IntPtr)m, m.Size)) { Assert.That(() => ms.Write(null, 0, 0), Throws.ArgumentNullException); var bytes = new byte[] { 0, 0, 0, 0, 0, 0, 0, 3 }; Assert.That(() => ms.Write(bytes, 1, 8), Throws.ArgumentException); Assert.That(() => ms.Write(bytes, -1, 8), Throws.TypeOf <ArgumentOutOfRangeException>()); Assert.That(() => ms.Write(bytes, 1, -8), Throws.TypeOf <ArgumentOutOfRangeException>()); Assert.That(() => ms.Write(new byte[22]), Throws.TypeOf <InsufficientMemoryException>()); ms.Write((SafeHGlobalHandle)null); Assert.That(ms.Position, Is.Zero); ms.Write((string[])null); Assert.That(ms.Position, Is.Zero); Assert.That(() => ms.Write(0L), Throws.Nothing); } using (var m = new SafeHGlobalHandle(100)) using (var ms = new MarshalingStream((IntPtr)m, m.Size)) { ms.Write(new[] { "A", "B", "C" }); Assert.That(ms.Position, Is.GreaterThan(0)); Assert.That(() => ms.Write(new byte[100], 0, 100), Throws.ArgumentException); } }
/// <summary> /// Marshals data from a managed list of strings to an unmanaged block of memory allocated by the <paramref name="memAlloc"/> method. /// </summary> /// <param name="values">The enumerated list of strings to marshal.</param> /// <param name="packing">The packing type for the strings.</param> /// <param name="memAlloc"> /// The function that allocates the memory for the block of strings (typically <see cref="Marshal.AllocCoTaskMem(int)"/> or <see cref="Marshal.AllocHGlobal(int)"/>. /// </param> /// <param name="bytesAllocated">The bytes allocated by the <paramref name="memAlloc"/> method.</param> /// <param name="charSet">The character set to use for the strings.</param> /// <param name="prefixBytes">Number of bytes preceding the trailing strings.</param> /// <returns> /// Pointer to the allocated native (unmanaged) array of strings stored using the <paramref name="packing"/> model and the character /// set defined by <paramref name="charSet"/>. /// </returns> public static IntPtr MarshalToPtr(this IEnumerable <string> values, StringListPackMethod packing, Func <int, IntPtr> memAlloc, out int bytesAllocated, CharSet charSet = CharSet.Auto, int prefixBytes = 0) { // Convert to list to avoid multiple iterations var list = values as IList <string> ?? (values != null ? new List <string>(values) : null); // Look at count and bail early if 0 var count = values?.Count() ?? 0; var chSz = StringHelper.GetCharSize(charSet); bytesAllocated = prefixBytes + (packing == StringListPackMethod.Concatenated ? chSz : IntPtr.Size); if (count == 0) { var ret = memAlloc(bytesAllocated); Marshal.Copy(new byte[bytesAllocated], 0, ret, bytesAllocated); return(ret); } // Check for empty and/or null strings if (packing == StringListPackMethod.Concatenated && list.Any(s => string.IsNullOrEmpty(s))) { throw new ArgumentException("Concatenated string arrays cannot contain empty or null strings."); } // Get size of output var sumStrLen = list.Sum(s => s == null ? 0 : s.Length + 1); bytesAllocated += sumStrLen * chSz; if (packing == StringListPackMethod.Packed) { bytesAllocated += (IntPtr.Size * count); } using (var ms = new MarshalingStream(memAlloc(bytesAllocated), bytesAllocated) { Position = prefixBytes, CharSet = charSet }) { if (packing == StringListPackMethod.Packed) { ms.Position += (count + 1) * IntPtr.Size; for (var i = 0; i < list.Count; i++) { ms.Poke(list[i] == null ? IntPtr.Zero : ms.Pointer.Offset(ms.Position), prefixBytes + (i * IntPtr.Size)); ms.Write(list[i]); } ms.Poke(IntPtr.Zero, prefixBytes + (count * IntPtr.Size)); } else { foreach (var s in list) { ms.Write(s); } ms.Write(""); } return(ms.Pointer); } }
public void SetLengthTest() { using (var m = new SafeHGlobalHandle(1000)) using (var ms = new MarshalingStream((IntPtr)m, m.Size)) { Assert.That(() => ms.SetLength(1), Throws.Exception); } }
public void FlushTest() { using (var m = new SafeHGlobalHandle(1000)) using (var ms = new MarshalingStream((IntPtr)m, m.Size)) { ms.Flush(); } }
public void PropTest() { using SafeHGlobalHandle m = new SafeHGlobalHandle(1000); using MarshalingStream ms = new MarshalingStream(m, m.Size); Assert.That(ms.Length, Is.EqualTo(1000)); Assert.That(ms.CanWrite, Is.True); Assert.That(ms.CanSeek, Is.True); Assert.That(ms.CanRead, Is.True); }
public void SeekTest() { using SafeHGlobalHandle m = new SafeHGlobalHandle(1000); using MarshalingStream ms = new MarshalingStream(m, m.Size); Assert.That(ms.Seek(20, SeekOrigin.Begin), Is.EqualTo(20)); Assert.That(ms.Seek(20, SeekOrigin.Current), Is.EqualTo(40)); Assert.That(ms.Seek(-100, SeekOrigin.End), Is.EqualTo(900)); Assert.That(() => ms.Seek(-1, SeekOrigin.Begin), Throws.ArgumentException); Assert.That(() => ms.Seek(1, SeekOrigin.End), Throws.ArgumentException); }
public void PropTest() { using (var m = new SafeHGlobalHandle(1000)) using (var ms = new MarshalingStream((IntPtr)m, m.Size)) { Assert.That(ms.Length, Is.EqualTo(1000)); Assert.That(ms.CanWrite, Is.True); Assert.That(ms.CanSeek, Is.True); Assert.That(ms.CanRead, Is.True); } }
public void PokeTest() { using SafeHGlobalHandle m = new SafeHGlobalHandle(10); using MarshalingStream ms = new MarshalingStream(m, m.Size); Assert.That(() => ms.Write(0x000001FF), Throws.Nothing); Assert.That(ms.Position, Is.EqualTo(sizeof(int))); ms.Seek(0, SeekOrigin.Begin); byte[] ba = new byte[] { 0x2 }; Assert.That(() => ms.Poke(null, 0), Throws.ArgumentNullException); Assert.That(() => ms.Poke(ba, 1000), Throws.ArgumentException); Assert.That(() => ms.Poke(ba, -1), Throws.TypeOf <ArgumentOutOfRangeException>()); ms.Poke(ba, 1); Assert.That(ms.Read <int>(), Is.EqualTo(0x00000102)); Assert.That(() => ms.Read <ulong>(), Throws.TypeOf <ArgumentOutOfRangeException>()); }
public void PokeTest() { using (var m = new SafeHGlobalHandle(10)) using (var ms = new MarshalingStream((IntPtr)m, m.Size)) { Assert.That(() => ms.Write(0x000001FF), Throws.Nothing); Assert.That(ms.Position, Is.EqualTo(sizeof(int))); ms.Seek(0, SeekOrigin.Begin); var ba = new byte[] { 0x2 }; Assert.That(() => ms.Poke(null, 0), Throws.ArgumentNullException); Assert.That(() => ms.Poke(ba, 1000), Throws.ArgumentException); Assert.That(() => ms.Poke(ba, -1), Throws.TypeOf <ArgumentOutOfRangeException>()); ms.Poke(ba, 1); Assert.That(ms.Read <int>(), Is.EqualTo(0x00000102)); Assert.That(() => ms.Read <Vanara.PInvoke.User32_Gdi.ICONINFO>(), Throws.TypeOf <ArgumentOutOfRangeException>()); } }
public void PokeTest1() { using SafeHGlobalHandle m = new SafeHGlobalHandle(100); using MarshalingStream ms = new MarshalingStream(m, m.Size); Assert.That(ms.Position, Is.Zero); Assert.That(() => ms.Write(new[] { 1L, 2L }), Throws.Nothing); byte[] bytes = new byte[] { 0, 0, 0, 0, 0, 0, 0, 3 }; ms.Write(bytes, 0, bytes.Length); Assert.That(ms.Position, Is.EqualTo(sizeof(long) * 2 + 8)); ms.Seek(0, SeekOrigin.Begin); Assert.That(() => ms.Poke(IntPtr.Zero, 1002), Throws.ArgumentException); Assert.That(() => ms.Poke(IntPtr.Zero, -1), Throws.TypeOf <ArgumentOutOfRangeException>()); ms.Poke(IntPtr.Zero, sizeof(long)); byte[] buf = new byte[24]; ms.Read(buf, 0, buf.Length); Assert.That(buf, Is.EquivalentTo(new byte[] { 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3 })); Assert.That(() => ms.Read(null, 0, 0), Throws.ArgumentNullException); Assert.That(() => ms.Read(buf, 0, 30), Throws.ArgumentException); Assert.That(() => ms.Read(buf, -1, 0), Throws.TypeOf <ArgumentOutOfRangeException>()); ms.Position = m.Size - 10; Assert.That(() => ms.Read(buf, 0, buf.Length), Throws.Nothing); }
public void MarshalingStreamTest() { using (var m = new SafeHGlobalHandle(1024)) using (var ms = new MarshalingStream((IntPtr)m, m.Size)) Assert.That(ms.Capacity, Is.EqualTo((long)m.Size)); }
public void SetLengthTest() { using SafeHGlobalHandle m = new SafeHGlobalHandle(1000); using MarshalingStream ms = new MarshalingStream(m, m.Size); Assert.That(() => ms.SetLength(1), Throws.Exception); }
public void FlushTest() { using SafeHGlobalHandle m = new SafeHGlobalHandle(1000); using MarshalingStream ms = new MarshalingStream(m, m.Size); ms.Flush(); }
public void MarshalingStreamTest() { using SafeHGlobalHandle m = new SafeHGlobalHandle(1024); using MarshalingStream ms = new MarshalingStream(m, m.Size); Assert.That(ms.Capacity, Is.EqualTo((long)m.Size)); }
/// <summary> /// Marshals data from a managed list of objects to an unmanaged block of memory allocated by the <paramref name="memAlloc"/> method. /// </summary> /// <param name="values">The enumerated list of objects to marshal.</param> /// <param name="memAlloc"> /// The function that allocates the memory for the block of objects (typically <see cref="Marshal.AllocCoTaskMem(int)"/> or <see cref="Marshal.AllocHGlobal(int)"/>. /// </param> /// <param name="bytesAllocated">The bytes allocated by the <paramref name="memAlloc"/> method.</param> /// <param name="referencePointers"> /// if set to <see langword="true"/> the pointer will be processed by storing a reference to the value; if <see langword="false"/>, /// the pointer value will be directly inserted into the array of pointers. /// </param> /// <param name="charSet">The character set to use for strings.</param> /// <param name="prefixBytes">Number of bytes preceding the allocated objects.</param> /// <returns>Pointer to the allocated native (unmanaged) array of objects stored using the character set defined by <paramref name="charSet"/>.</returns> public static IntPtr MarshalObjectsToPtr(this IEnumerable <object> values, Func <int, IntPtr> memAlloc, out int bytesAllocated, bool referencePointers = false, CharSet charSet = CharSet.Auto, int prefixBytes = 0) { // Convert to list to avoid multiple iterations var list = values as IList <object> ?? (values != null ? new List <object>(values) : null); // Look at count and bail early if 0 var count = values?.Count() ?? 0; bytesAllocated = prefixBytes + IntPtr.Size; if (count == 0) { var ret = memAlloc(bytesAllocated); ret.FillMemory(0, bytesAllocated); return(ret); } // Get size of output (array size + objects sizes) var chSz = StringHelper.GetCharSize(charSet); bytesAllocated += IntPtr.Size * count; bytesAllocated += list.Sum(GetSize); // Create pointer array var ptrs = new IntPtr[count + 1]; using (var ms = new MarshalingStream(memAlloc(bytesAllocated), bytesAllocated) { Position = prefixBytes, CharSet = charSet }) { ms.Position += (count + 1) * IntPtr.Size; for (var i = 0; i < list.Count; i++) { if (!referencePointers && list[i] is IntPtr p) { ptrs[i] = p; } else { ptrs[i] = list[i] is null ? IntPtr.Zero : ms.Pointer.Offset(ms.Position); ms.Write(list[i]); } } ms.Position = 0; ms.Write(ptrs); return(ms.Pointer); } int GetSize(object o) { if (o is null) { return(0); } if (o is string s) { return((s.Length + 1) * chSz); } if (o is IntPtr) { return(referencePointers ? IntPtr.Size : 0); } return(Marshal.SizeOf(o)); } }