/// <summary> /// Reads a number of elements from a memory location into the provided buffer starting at the specified index. /// </summary> /// <typeparam name="T">The structure type</typeparam> /// <param name="buffer">The destination buffer.</param> /// <param name="source">The source memory location.</param> /// <param name="index">The start index within <paramref name="buffer"/>.</param> /// <param name="count">The number of elements to read.</param> public static unsafe void ReadArray <T>(T[] buffer, IntPtr source, int index, int count) where T : struct { uint elementSize = (uint)SizeOf <T>(); if (buffer == null) { throw new ArgumentNullException(nameof(buffer)); } if (count < 0) { throw new ArgumentOutOfRangeException(nameof(count)); } if (index < 0) { throw new ArgumentOutOfRangeException(nameof(index)); } if (buffer.Length - index < count) { throw new ArgumentException("Invalid offset into array specified by index and count"); } void *ptr = source.ToPointer(); byte *p = (byte *)FastStructure.GetPtr <T>(ref buffer[0]); Buffer.MemoryCopy(ptr, p + (index * elementSize), elementSize * count, elementSize * count); }
/// <summary> /// Writes an array of <typeparamref name="T"/> into the buffer /// </summary> /// <typeparam name="T">A structure type</typeparam> /// <param name="source">An array of <typeparamref name="T"/> to be written. The length of this array controls the number of elements to be written.</param> /// <param name="bufferPosition">The offset within the buffer region of the shared memory to write to.</param> //protected virtual void Write<T>(T[] source, long bufferPosition = 0) // where T : struct //{ // Write<T>(source, 0, bufferPosition); //} /// <summary> /// Writes an array of <typeparamref name="T"/> into the buffer /// </summary> /// <typeparam name="T">A structure type</typeparam> /// <param name="source">An array of <typeparamref name="T"/> to be written. The length of this array controls the number of elements to be written.</param> /// <param name="index">The index within the array to start writing from.</param> /// <param name="bufferPosition">The offset within the buffer region of the shared memory to write to.</param> //protected virtual void Write<T>(T[] source, int index, long bufferPosition = 0) // where T : struct //{ // FastStructure.WriteArray<T>((IntPtr)(BufferStartPtr + bufferPosition), source, index, source.Length - index); //} /// <summary> /// Writes an array of <typeparamref name="T"/> into the buffer /// </summary> /// <typeparam name="T">A structure type</typeparam> /// <param name="source">The source data to be written to the buffer</param> /// <param name="index">The start index within <paramref name="source"/>.</param> /// <param name="count">The number of elements to write.</param> /// <param name="bufferPosition">The offset within the buffer region of the shared memory to write to.</param> protected virtual void WriteArray <T>(T[] source, int index, int count, long bufferPosition = 0) where T : struct { FastStructure.WriteArray <T>((IntPtr)(BufferStartPtr + bufferPosition), source, index, count); }
/// <summary> /// Loads the generic value type <typeparamref name="T"/> from a pointer. This is achieved by emitting a <see cref="DynamicMethod"/> that returns the value in the memory location as a <typeparamref name="T"/>. /// <para>The equivalent non-generic C# code:</para> /// <code> /// unsafe MyStruct ReadFromPointer(byte* pointer) /// { /// return *(MyStruct*)pointer; /// } /// </code> /// </summary> /// <typeparam name="T">Any value/structure type</typeparam> /// <param name="pointer">Unsafe pointer to memory to load the value from</param> /// <returns>The newly loaded value</returns> public static unsafe T PtrToStructure <T>(IntPtr pointer) where T : struct { return(FastStructure <T> .PtrToStructure(pointer)); }
/// <summary> /// Writes the generic value type <typeparamref name="T"/> to the location specified by a pointer. This is achieved by emitting a <see cref="DynamicMethod"/> that copies the value from the referenced structure into the specified memory location. /// <para>There is no exact equivalent possible in C#, the closest possible (generates the same IL) is the following code:</para> /// <code> /// unsafe void WriteToPointer(ref SharedHeader dest, ref SharedHeader src) /// { /// dest = src; /// } /// </code> /// </summary> /// <typeparam name="T"></typeparam> /// <param name="pointer"></param> /// <param name="structure"></param> public static unsafe void StructureToPtr <T>(ref T structure, IntPtr pointer) where T : struct { FastStructure <T> .StructureToPtr(ref structure, pointer); }
/// <summary> /// Retrieve a pointer to the passed generic structure type. This is achieved by emitting a <see cref="DynamicMethod"/> to retrieve a pointer to the structure. /// </summary> /// <typeparam name="T"></typeparam> /// <param name="structure"></param> /// <returns>A pointer to the provided structure in memory.</returns> /// <see cref="FastStructure{T}.GetPtr"/> public static unsafe void *GetPtr <T>(ref T structure) where T : struct { return(FastStructure <T> .GetPtr(ref structure)); }