예제 #1
0
        /// <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(RS.InvalidOffsetIntoArray);
            }

            void *ptr = source.ToPointer();
            byte *p   = (byte *)FastStructure.GetPtr <T>(ref buffer[0]);

#if NETFX
            UnsafeNativeMethods.CopyMemoryPtr(p + (index * elementSize), ptr, (uint)(elementSize * count));
#else
            Buffer.MemoryCopy(ptr, p + (index * elementSize), elementSize * count, elementSize * count);
#endif
        }
예제 #2
0
        /// <summary>
        /// Writes the structure array buffer to the next available node for writing.
        /// </summary>
        /// <param name="source">Reference to the buffer to write.</param>
        /// <param name="startIndex">The index within the buffer to start writing from.</param>
        /// <param name="timeout">The maximum number of milliseconds to wait for a node to become available for writing. Defaults to 1000 (ms).</param>
        /// <returns>The number of elements written.</returns>
        /// <remarks><![CDATA[
        /// The maximum number of elements that can be written can be calculated by the following formula:
        /// ```C#
        /// Math.Min(source - startIndex, NodeBufferSize) / FastStructure.SizeOf<T>()
        /// ```
        /// ]]></remarks>
        public virtual int Write <T>(T[] source, int startIndex = 0, int timeout = 1000)
            where T : struct
        {
            // Grab a node for writing
            Node *node = GetNodeForWriting(timeout);

            if (node == null)
            {
                return(0);
            }

            // Write the data using the FastStructure class (much faster than the MemoryMappedViewAccessor WriteArray<T> method)
            int count = Math.Min(source.Length - startIndex, NodeBufferSize / FastStructure.SizeOf <T>());

            base.WriteArray <T>(source, startIndex, count, node->Offset);
            node->AmountWritten = count * FastStructure.SizeOf <T>();

            // Writing is complete, make node readable
            PostNode(node);

            return(count);
        }
예제 #3
0
        /// <summary>
        /// Reads the next available node for reading into the specified structure array.
        /// </summary>
        /// <typeparam name="T">The structure type to be read.</typeparam>
        /// <param name="destination">Reference to the buffer.</param>
        /// <param name="startIndex">The index within the destination to start writing to.</param>
        /// <param name="timeout">The maximum number of milliseconds to wait for a node to become available for reading. Defaults to 1000 (ms).</param>
        /// <returns>The number of elements read into destination.</returns>
        /// <remarks><![CDATA[
        /// The maximum number of elements that can be read can be determined by the following formula:
        ///
        /// ```C#
        /// Math.Min(destination.Length - startIndex, Node.AmountWritten / FastStructure.SizeOf<T>())
        /// ```
        /// ]]></remarks>
        public virtual int Read <T>(T[] destination, int startIndex = 0, int timeout = 1000)
            where T : struct
        {
            Node *node = GetNodeForReading(timeout);

            if (node == null)
            {
                return(0);
            }

            // Copy the data using the FastStructure class (much faster than the MemoryMappedViewAccessor ReadArray<T> method)
            int count = Math.Min(destination.Length - startIndex, node->AmountWritten / FastStructure.SizeOf <T>());

            base.ReadArray <T>(destination, startIndex, count, node->Offset);

            // Return the node for further writing
            ReturnNode(node);

            return(count);
        }
예제 #4
0
 /// <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.
 /// </summary>
 /// <typeparam name="T">The structure type.</typeparam>
 /// <param name="pointer">The pointer position to write.</param>
 /// <param name="structure">The structure to write into memory.</param>
 /// <remarks>
 /// There is no exact equivalent possible in C#, the closest possible (generates the same IL) is the following code:
 /// ```C#
 /// unsafe void WriteToPointer(ref SharedHeader dest, ref SharedHeader src)
 /// {
 ///     dest = src;
 /// }
 /// ```
 /// </remarks>
 public static unsafe void StructureToPtr <T>(ref T structure, IntPtr pointer)
     where T : struct
 {
     FastStructure <T> .StructureToPtr(ref structure, pointer);
 }
예제 #5
0
 /// <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"/>.
 /// </summary>
 /// <typeparam name="T">The structure type.</typeparam>
 /// <param name="pointer">Unsafe pointer to memory to load the value from.</param>
 /// <returns>
 /// The value of the structure loaded from memory.
 /// </returns>
 /// <remarks>
 /// The following code demonstrates the equivalent non-generic C# code:
 /// ```C#
 /// unsafe MyStruct ReadFromPointer(byte* pointer)
 /// {
 ///     return *(MyStruct*)pointer;
 /// }
 /// ```
 /// </remarks>
 public static unsafe T PtrToStructure <T>(IntPtr pointer)
     where T : struct
 {
     return(FastStructure <T> .PtrToStructure(pointer));
 }
예제 #6
0
 /// <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">The structure type.</typeparam>
 /// <param name="structure">The structure to search.</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));
 }
예제 #7
0
 /// <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="destination">The destination buffer.</param>
 /// <param name="index">The start index within <paramref name="destination"/>.</param>
 /// <param name="count">The number of elements to read.</param>
 /// <param name="bufferPosition">The source offset within the buffer region of the shared memory.</param>
 protected virtual void ReadArray <T>(T[] destination, int index, int count, long bufferPosition)
     where T : struct
 {
     FastStructure.ReadArray <T>(destination, (IntPtr)(BufferStartPtr + bufferPosition), index, count);
 }
예제 #8
0
 /// <summary>
 /// Reads an array of <typeparamref name="T"/> from the buffer.
 /// </summary>
 /// <typeparam name="T">A structure type.</typeparam>
 /// <param name="destination">Array that will contain the values read from the buffer. The length of this array controls the number of elements to read.</param>
 /// <param name="bufferPosition">The offset within the buffer region of the shared memory to read from.</param>
 protected virtual void Read <T>(T[] destination, long bufferPosition = 0)
     where T : struct
 {
     FastStructure.ReadArray <T>(destination, (IntPtr)(BufferStartPtr + bufferPosition), 0, destination.Length);
 }
예제 #9
0
 /// <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);
 }