// Copyright (c) 2010-2014 SharpDX - Alexandre Mutel // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. using System; using System.Runtime.InteropServices; namespace SharpDX { /// /// Pointer to a native buffer with a specific size. /// [StructLayout(LayoutKind.Sequential)] public struct DataPointer : IEquatable { /// /// Gets an Empty Data Pointer. /// public static readonly DataPointer Zero = new DataPointer(IntPtr.Zero, 0); /// /// Initializes a new instance of the struct. /// /// The pointer. /// The size. public DataPointer(IntPtr pointer, int size) { Pointer = pointer; Size = size; } /// /// Initializes a new instance of the struct. /// /// The pointer. /// The size. public unsafe DataPointer(void* pointer, int size) { Pointer = (IntPtr)pointer; Size = size; } /// /// Pointer to the buffer. /// public IntPtr Pointer; /// /// Size in bytes of the buffer. /// public int Size; /// /// Gets a value indicating whether this instance is empty (zeroed). /// /// true if this instance is empty; otherwise, false. public bool IsEmpty { get { return Equals(Zero); } } public bool Equals(DataPointer other) { return Pointer.Equals(other.Pointer) && Size == other.Size; } public override bool Equals(object obj) { if (ReferenceEquals(null, obj)) return false; return obj is DataPointer && Equals((DataPointer) obj); } public override int GetHashCode() { unchecked { return (Pointer.GetHashCode() * 397) ^ Size; } } /// /// Converts this DataPointer to a . /// /// An instance of a . public DataStream ToDataStream() { if (Pointer == IntPtr.Zero) throw new InvalidOperationException("DataPointer is Zero"); return new DataStream(this); } /// /// Converts this DataPointer to a . /// /// An instance of a . public DataBuffer ToDataBuffer() { if (Pointer == IntPtr.Zero) throw new InvalidOperationException("DataPointer is Zero"); return new DataBuffer(this); } /// /// Converts this instance to a read only byte buffer. /// /// A readonly byte buffer. /// /// DataPointer is Zero /// or /// Size cannot be < 0 /// 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]; Utilities.Read(Pointer, buffer, 0, Size); return buffer; } /// /// Converts this instance to a read only typed buffer. /// /// Type of a buffer element /// A readonly typed buffer. /// DataPointer is Zero public T[] ToArray() where T : struct { if (Pointer == IntPtr.Zero) throw new InvalidOperationException("DataPointer is Zero"); var buffer = new T[Size / Utilities.SizeOf()]; CopyTo(buffer, 0, buffer.Length); return buffer; } /// /// Reads the content of the unmanaged memory location of this instance to the specified buffer. /// /// Type of a buffer element /// The buffer. /// The offset in the array to write to. /// The number of T element to read from the memory location. /// buffer /// DataPointer is Zero /// buffer;Total buffer size cannot be larger than size of this data pointer public void CopyTo(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 * Utilities.SizeOf() > Size) throw new ArgumentOutOfRangeException("buffer", "Total buffer size cannot be larger than size of this data pointer"); Utilities.Read(Pointer, buffer, offset, count); } /// /// Writes the content of the specified buffer to the unmanaged memory location of this instance. /// /// Type of a buffer element /// The buffer. /// buffer /// DataPointer is Zero public void CopyFrom(T[] buffer) where T : struct { if(buffer == null) throw new ArgumentNullException("buffer"); if (Pointer == IntPtr.Zero) throw new InvalidOperationException("DataPointer is Zero"); CopyFrom(buffer, 0, buffer.Length); } /// /// Writes the content of the specified buffer to the unmanaged memory location of this instance. /// /// /// The buffer to read from. /// The offset in the array to read from. /// The number of T element to write to the memory location. /// buffer /// DataPointer is Zero /// buffer;Total buffer size cannot be larger than size of this data pointer public void CopyFrom(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 * Utilities.SizeOf() > Size) throw new ArgumentOutOfRangeException("buffer", "Total buffer size cannot be larger than size of this data pointer"); Utilities.Write(Pointer, buffer, offset, count); } /// /// Implements the ==. /// /// The left. /// The right. /// The result of the operator. public static bool operator ==(DataPointer left, DataPointer right) { return left.Equals(right); } /// /// Implements the !=. /// /// The left. /// The right. /// The result of the operator. public static bool operator !=(DataPointer left, DataPointer right) { return !left.Equals(right); } } }