예제 #1
0
 /// <summary>
 /// Gets a single value from the current buffer at the specified position.
 /// </summary>
 /// <typeparam name="T">The type of the value to be read from the buffer.</typeparam>
 /// <param name="positionInBytes">Relative position in bytes from the beginning of the buffer to get the data from.</param>
 /// <param name="value">The value as out.</param>
 /// <returns>The value that was read.</returns>
 public void Get <T>(int positionInBytes, out T value) where T : struct
 {
     unsafe
     {
         SdxUtilities.ReadOut((IntPtr)(_buffer + positionInBytes), out value);
     }
 }
예제 #2
0
 /// <summary>
 ///   Gets a sequence of elements from a position in the buffer into a target buffer.
 /// </summary>
 /// <param name="positionInBytes">Relative position in bytes from the beginning of the buffer to get the data from.</param>
 /// <param name = "buffer">An array of values to be read from the buffer.</param>
 /// <param name = "offset">The zero-based byte offset in buffer at which to begin storing
 ///   the data read from the current buffer.</param>
 /// <param name = "count">The number of values to be read from the current buffer.</param>
 public void GetRange <T>(int positionInBytes, T[] buffer, int offset, int count) where T : struct
 {
     unsafe
     {
         SdxUtilities.Read((IntPtr)(_buffer + positionInBytes), buffer, offset, count);
     }
 }
예제 #3
0
 /// <summary>
 ///   Sets a range of data to a specified position into the buffer.
 /// </summary>
 /// <param name="positionInBytes">Relative position in bytes from the beginning of the buffer to set the data to.</param>
 /// <param name = "source">A pointer to the location to start copying from.</param>
 /// <param name = "count">The number of bytes to copy from source to the current buffer.</param>
 public void Set(int positionInBytes, IntPtr source, long count)
 {
     unsafe
     {
         SdxUtilities.CopyMemory((IntPtr)(_buffer + positionInBytes), source, (int)count);
     }
 }
예제 #4
0
 /// <summary>
 ///   Sets an array of values to a specified position into the buffer.
 /// </summary>
 /// <typeparam name = "T">The type of the values to be written to the buffer.</typeparam>
 /// <param name="positionInBytes">Relative position in bytes from the beginning of the buffer to set the data to.</param>
 /// <param name = "data">An array of values to be written to the buffer.</param>
 /// <param name = "offset">The zero-based offset in data at which to begin copying values to the current buffer.</param>
 /// <param name = "count">The number of values to be written to the current buffer. If this is zero,
 ///   all of the contents <paramref name = "data" /> will be written.</param>
 public void Set <T>(int positionInBytes, T[] data, int offset, int count) where T : struct
 {
     unsafe
     {
         SdxUtilities.Write((IntPtr)(_buffer + positionInBytes), data, offset, count);
     }
 }
예제 #5
0
        /// <summary>
        /// Creates the specified user buffer.
        /// </summary>
        /// <typeparam name="T">Type of the buffer.</typeparam>
        /// <param name="userBuffer">The buffer to use as a DataBuffer.</param>
        /// <param name="index">Index inside the buffer in terms of element count (not size in bytes).</param>
        /// <param name="pinBuffer">True to keep the managed buffer and pin it, false will allocate unmanaged memory and make a copy of it. Default is true.</param>
        /// <returns>An instance of a DataBuffer</returns>
        public static DataBuffer Create <T>(T[] userBuffer, int index = 0, bool pinBuffer = true) where T : struct
        {
            unsafe
            {
                if (userBuffer == null)
                {
                    throw new ArgumentNullException("userBuffer");
                }

                if (index < 0 || index > userBuffer.Length)
                {
                    throw new ArgumentException("Index is out of range [0, userBuffer.Length-1]", "index");
                }

                DataBuffer buffer;

                var sizeOfBuffer = SdxUtilities.SizeOf(userBuffer);
                var indexOffset  = index * SdxUtilities.SizeOf <T>();

                if (pinBuffer)
                {
                    var handle = GCHandle.Alloc(userBuffer, GCHandleType.Pinned);
                    buffer = new DataBuffer(indexOffset + (byte *)handle.AddrOfPinnedObject(), sizeOfBuffer - indexOffset, handle);
                }
                else
                {
                    // The .NET Native compiler crashes if '(IntPtr)' is removed.
                    buffer = new DataBuffer(indexOffset + (byte *)(IntPtr)Interop.Fixed(userBuffer), sizeOfBuffer - indexOffset, true);
                }

                return(buffer);
            }
        }
예제 #6
0
        /// <summary>
        /// Releases unmanaged and - optionally - managed resources
        /// </summary>
        /// <param name="disposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
#if !WINDOWS_UWP
                if (_blob != null)
                {
                    _blob.Dispose();
                    _blob = null;
                }
#endif
            }

            if (_gCHandle.IsAllocated)
            {
                _gCHandle.Free();
            }

            unsafe
            {
                if (_ownsBuffer && _buffer != (sbyte *)0)
                {
                    SdxUtilities.FreeMemory((IntPtr)_buffer);
                    _buffer = (sbyte *)0;
                }
            }
        }
예제 #7
0
 /// <summary>
 /// When overridden in a derived class, writes a sequence of bytes to the current stream and advances the current position within this stream by the number of bytes written.
 /// </summary>
 /// <param name="buffer">An array of bytes. This method copies <paramref name="count" /> bytes from <paramref name="buffer" /> to the current stream.</param>
 /// <param name="offset">The zero-based byte offset in <paramref name="buffer" /> at which to begin copying bytes to the current stream.</param>
 /// <param name="count">The number of bytes to be written to the current stream.</param>
 public void Write(IntPtr buffer, int offset, int count)
 {
     unsafe
     {
         SdxUtilities.CopyMemory((IntPtr)(_buffer + _position), new IntPtr((byte *)buffer + offset), count);
         _position += count;
     }
 }
예제 #8
0
 /// <summary>
 ///   Gets a single value from the current buffer at the specified position.
 /// </summary>
 /// <param name="positionInBytes">Relative position in bytes from the beginning of the buffer to get the data from.</param>
 /// <typeparam name = "T">The type of the value to be read from the buffer.</typeparam>
 /// <returns>The value that was read.</returns>
 public T Get <T>(int positionInBytes) where T : struct
 {
     unsafe
     {
         T result = default(T);
         SdxUtilities.Read((IntPtr)(_buffer + positionInBytes), ref result);
         return(result);
     }
 }
예제 #9
0
 /// <summary>
 ///   Gets an array of values from a position in the buffer.
 /// </summary>
 /// <param name="positionInBytes">Relative position in bytes from the beginning of the buffer to get the data from.</param>
 /// <param name="count">number of T instance to get from the positionInBytes</param>
 /// <typeparam name = "T">The type of the values to be read from the buffer.</typeparam>
 /// <returns>An array of values that was read from the current buffer.</returns>
 public T[] GetRange <T>(int positionInBytes, int count) where T : struct
 {
     unsafe
     {
         var result = new T[count];
         SdxUtilities.Read((IntPtr)(_buffer + positionInBytes), result, 0, count);
         return(result);
     }
 }
예제 #10
0
        /// <summary>
        /// Converts this instance to a read only typed buffer.
        /// </summary>
        /// <typeparam name="T">Type of a buffer element</typeparam>
        /// <returns>A readonly typed buffer.</returns>
        /// <exception cref="System.InvalidOperationException">DataPointer is Zero</exception>
        public                             T[] ToArray <T>() where T : struct
        {
            if (Pointer == IntPtr.Zero)
            {
                throw new InvalidOperationException("DataPointer is Zero");
            }
            var buffer = new T[Size / SdxUtilities.SizeOf <T>()];

            CopyTo(buffer, 0, buffer.Length);
            return(buffer);
        }
예제 #11
0
 /// <summary>
 ///   Writes a single value to the stream, and advances the current position
 ///   within this stream by the number of bytes written.
 /// </summary>
 /// <remarks>
 /// In order to provide faster read/write, this operation doesn't check stream bound.
 /// A client must carefully not read/write above the size of this datastream.
 /// </remarks>
 /// <typeparam name = "T">The type of the value to be written to the stream.</typeparam>
 /// <param name = "value">The value to write to the stream.</param>
 /// <exception cref = "T:System.NotSupportedException">The stream does not support writing.</exception>
 public void Write <T>(T value) where T : struct
 {
     if (!_canWrite)
     {
         throw new NotSupportedException();
     }
     unsafe
     {
         _position = (byte *)SdxUtilities.WriteAndPosition((IntPtr)(_buffer + _position), ref value) - _buffer;
     }
 }
예제 #12
0
        /// <summary>
        ///   Initializes a new instance of the <see cref = "DataBuffer" /> class, and allocates a new buffer to use as a backing store.
        /// </summary>
        /// <param name = "sizeInBytes">The size of the buffer to be allocated, in bytes.</param>
        /// <exception cref = "T:System.ArgumentOutOfRangeException">
        ///   <paramref name = "sizeInBytes" /> is less than 1.</exception>
        public DataBuffer(int sizeInBytes)
        {
            unsafe
            {
                Debug.Assert(sizeInBytes > 0);

                _buffer     = (sbyte *)SdxUtilities.AllocateMemory(sizeInBytes);
                _size       = sizeInBytes;
                _ownsBuffer = true;
            }
        }
예제 #13
0
        /// <summary>
        ///   Writes an array of values to the current stream, and advances the current position
        ///   within this stream by the number of bytes written.
        /// </summary>
        /// <remarks>
        /// In order to provide faster read/write, this operation doesn't check stream bound.
        /// A client must carefully not read/write above the size of this datastream.
        /// </remarks>
        /// <typeparam name = "T">The type of the values to be written to the stream.</typeparam>
        /// <param name = "data">An array of values to be written to the stream.</param>
        /// <param name = "offset">The zero-based offset in data at which to begin copying values to the current stream.</param>
        /// <param name = "count">The number of values to be written to the current stream. If this is zero,
        ///   all of the contents <paramref name = "data" /> will be written.</param>
        /// <exception cref = "T:System.NotSupportedException">This stream does not support writing.</exception>
        public void WriteRange <T>(T[] data, int offset, int count) where T : struct
        {
            unsafe
            {
                if (!_canWrite)
                {
                    throw new NotSupportedException();
                }

                _position = (byte *)SdxUtilities.Write((IntPtr)(_buffer + _position), data, offset, count) - _buffer;
            }
        }
예제 #14
0
        /// <summary>
        ///   Initializes a new instance of the <see cref = "DataStream" /> class, and allocates a new buffer to use as a backing store.
        /// </summary>
        /// <param name = "sizeInBytes">The size of the buffer to be allocated, in bytes.</param>
        /// <param name = "canRead">
        ///   <c>true</c> if reading from the buffer should be allowed; otherwise, <c>false</c>.</param>
        /// <param name = "canWrite">
        ///   <c>true</c> if writing to the buffer should be allowed; otherwise, <c>false</c>.</param>
        public DataStream(int sizeInBytes, bool canRead, bool canWrite)
        {
            unsafe
            {
                Debug.Assert(sizeInBytes > 0);

                _buffer     = (byte *)SdxUtilities.AllocateMemory(sizeInBytes);
                _size       = sizeInBytes;
                _ownsBuffer = true;
                _canRead    = canRead;
                _canWrite   = canWrite;
            }
        }
예제 #15
0
        /// <summary>
        ///   Reads a sequence of elements from the current stream into a target buffer and
        ///   advances the position within the stream by the number of bytes read.
        /// </summary>
        /// <remarks>
        /// In order to provide faster read/write, this operation doesn't check stream bound.
        /// A client must carefully not read/write above the size of this datastream.
        /// </remarks>
        /// <param name = "buffer">An array of values to be read from the stream.</param>
        /// <param name = "offset">The zero-based byte offset in buffer at which to begin storing
        ///   the data read from the current stream.</param>
        /// <param name = "count">The number of values to be read from the current stream.</param>
        /// <returns>The number of bytes read from the stream.</returns>
        /// <exception cref = "T:System.NotSupportedException">This stream does not support reading.</exception>
        public int ReadRange <T>(T[] buffer, int offset, int count) where T : struct
        {
            unsafe
            {
                if (!_canRead)
                {
                    throw new NotSupportedException();
                }

                var oldPosition = _position;
                _position = (byte *)SdxUtilities.Read((IntPtr)(_buffer + _position), buffer, offset, count) - _buffer;
                return((int)(_position - oldPosition));
            }
        }
예제 #16
0
        /// <summary>
        /// Converts this instance to a read only byte buffer.
        /// </summary>
        /// <returns>A readonly byte buffer.</returns>
        /// <exception cref="System.InvalidOperationException">
        /// DataPointer is Zero
        /// or
        /// Size cannot be &lt; 0
        /// </exception>
        public byte[] ToArray()
        {
            if (Pointer == IntPtr.Zero)
            {
                throw new InvalidOperationException("DataPointer is Zero");
            }
            if (Size < 0)
            {
                throw new InvalidOperationException("Size cannot be < 0");
            }
            var buffer = new byte[Size];

            SdxUtilities.Read(Pointer, buffer, 0, Size);
            return(buffer);
        }
예제 #17
0
        /// <summary>
        ///   Reads a single value from the current stream and advances the current
        ///   position within this stream by the number of bytes read.
        /// </summary>
        /// <remarks>
        /// In order to provide faster read/write, this operation doesn't check stream bound.
        /// A client must carefully not read/write above the size of this datastream.
        /// </remarks>
        /// <typeparam name = "T">The type of the value to be read from the stream.</typeparam>
        /// <returns>The value that was read.</returns>
        /// <exception cref = "T:System.NotSupportedException">This stream does not support reading.</exception>
        public T Read <T>() where T : struct
        {
            unsafe
            {
                if (!_canRead)
                {
                    throw new NotSupportedException();
                }

                byte *from   = _buffer + _position;
                T     result = default(T);
                _position = (byte *)SdxUtilities.ReadAndPosition((IntPtr)from, ref result) - _buffer;
                return(result);
            }
        }
예제 #18
0
        /// <summary>
        ///   Reads an array of values from the current stream, and advances the current position
        ///   within this stream by the number of bytes written.
        /// </summary>
        /// <remarks>
        /// In order to provide faster read/write, this operation doesn't check stream bound.
        /// A client must carefully not read/write above the size of this datastream.
        /// </remarks>
        /// <typeparam name = "T">The type of the values to be read from the stream.</typeparam>
        /// <returns>An array of values that was read from the current stream.</returns>
        public T[] ReadRange <T>(int count) where T : struct
        {
            unsafe
            {
                if (!_canRead)
                {
                    throw new NotSupportedException();
                }

                byte *from   = _buffer + _position;
                var   result = new T[count];
                _position = (byte *)SdxUtilities.Read((IntPtr)from, result, 0, count) - _buffer;
                return(result);
            }
        }
예제 #19
0
        internal unsafe DataBuffer(void *buffer, int sizeInBytes, bool makeCopy)
        {
            Debug.Assert(sizeInBytes > 0);

            if (makeCopy)
            {
                _buffer = (sbyte *)SdxUtilities.AllocateMemory(sizeInBytes);
                SdxUtilities.CopyMemory((IntPtr)_buffer, (IntPtr)buffer, sizeInBytes);
            }
            else
            {
                _buffer = (sbyte *)buffer;
            }
            _size       = sizeInBytes;
            _ownsBuffer = makeCopy;
        }
예제 #20
0
 internal unsafe DataStream(void *buffer, int sizeInBytes, bool canRead, bool canWrite, bool makeCopy)
 {
     Debug.Assert(sizeInBytes > 0);
     if (makeCopy)
     {
         _buffer = (byte *)SdxUtilities.AllocateMemory(sizeInBytes);
         SdxUtilities.CopyMemory((IntPtr)_buffer, (IntPtr)buffer, sizeInBytes);
     }
     else
     {
         _buffer = (byte *)buffer;
     }
     _size       = sizeInBytes;
     _canRead    = canRead;
     _canWrite   = canWrite;
     _ownsBuffer = makeCopy;
 }
예제 #21
0
        /// <summary>
        ///   Writes a range of bytes to the current stream, and advances the current position
        ///   within this stream by the number of bytes written.
        /// </summary>
        /// <remarks>
        /// In order to provide faster read/write, this operation doesn't check stream bound.
        /// A client must carefully not read/write above the size of this datastream.
        /// </remarks>
        /// <param name = "source">A pointer to the location to start copying from.</param>
        /// <param name = "count">The number of bytes to copy from source to the current stream.</param>
        /// <exception cref = "T:System.NotSupportedException">This stream does not support writing.</exception>
        public void WriteRange(IntPtr source, long count)
        {
            unsafe
            {
                if (!_canWrite)
                {
                    throw new NotSupportedException();
                }

                Debug.Assert(_canWrite);
                Debug.Assert(source != IntPtr.Zero);
                Debug.Assert(count > 0);
                Debug.Assert((_position + count) <= _size);

                // TODO: use Interop.memcpy
                SdxUtilities.CopyMemory((IntPtr)(_buffer + _position), source, (int)count);
                _position += count;
            }
        }
예제 #22
0
 /// <summary>
 /// Writes the content of the specified buffer to the unmanaged memory location of this instance.
 /// </summary>
 /// <typeparam name="T"></typeparam>
 /// <param name="buffer">The buffer to read from.</param>
 /// <param name="offset">The offset in the array to read from.</param>
 /// <param name="count">The number of T element to write to the memory location.</param>
 /// <exception cref="System.ArgumentNullException">buffer</exception>
 /// <exception cref="System.InvalidOperationException">DataPointer is Zero</exception>
 /// <exception cref="System.ArgumentOutOfRangeException">buffer;Total buffer size cannot be larger than size of this data pointer</exception>
 public void CopyFrom <T>(T[] buffer, int offset, int count) where T : struct
 {
     if (buffer == null)
     {
         throw new ArgumentNullException("buffer");
     }
     if (Pointer == IntPtr.Zero)
     {
         throw new InvalidOperationException("DataPointer is Zero");
     }
     if (offset < 0)
     {
         throw new ArgumentOutOfRangeException("offset", "Must be >= 0");
     }
     if (count <= 0)
     {
         throw new ArgumentOutOfRangeException("count", "Must be > 0");
     }
     if (count * SdxUtilities.SizeOf <T>() > Size)
     {
         throw new ArgumentOutOfRangeException("buffer", "Total buffer size cannot be larger than size of this data pointer");
     }
     SdxUtilities.Write(Pointer, buffer, offset, count);
 }
예제 #23
0
 /// <summary>
 /// Clears the buffer.
 /// </summary>
 public unsafe void Clear(byte value = 0)
 {
     SdxUtilities.ClearMemory((IntPtr)_buffer, value, Size);
 }