using System; using System.Collections; using System.Collections.Generic; using System.Runtime.InteropServices; namespace UTJ.FbxExporter { public class PinnedArray : IDisposable, IEnumerable, IEnumerable { public PinnedArray(int size = 0) { this.m_data = new T[size]; this.m_gch = GCHandle.Alloc(this.m_data, GCHandleType.Pinned); } public PinnedArray(T[] data, bool clone = false) { this.m_data = ((!clone) ? data : ((T[])data.Clone())); this.m_gch = GCHandle.Alloc(this.m_data, GCHandleType.Pinned); } public int Length { get { return this.m_data.Length; } } public T this[int i] { get { return this.m_data[i]; } set { this.m_data[i] = value; } } public T[] Array { get { return this.m_data; } } public IntPtr Pointer { get { return (this.m_data.Length != 0) ? this.m_gch.AddrOfPinnedObject() : IntPtr.Zero; } } public PinnedArray Clone() { return new PinnedArray((T[])this.m_data.Clone(), false); } public bool Assign(T[] source) { if (source != null && this.m_data.Length == source.Length) { System.Array.Copy(source, this.m_data, this.m_data.Length); return true; } return false; } public void Dispose() { this.Dispose(true); GC.SuppressFinalize(this); } protected virtual void Dispose(bool disposing) { if (disposing && this.m_gch.IsAllocated) { this.m_gch.Free(); } } public IEnumerator GetEnumerator() { return (IEnumerator)this.m_data.GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return this.GetEnumerator(); } public static implicit operator IntPtr(PinnedArray v) { return (v != null) ? v.Pointer : IntPtr.Zero; } public static implicit operator T[](PinnedArray v) { return (v != null) ? v.Array : null; } private T[] m_data; private GCHandle m_gch; } }