PinnedArray.cs 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using System.Runtime.InteropServices;
  5. namespace UTJ.FbxExporter
  6. {
  7. public class PinnedArray<T> : IDisposable, IEnumerable<T>, IEnumerable
  8. {
  9. public PinnedArray(int size = 0)
  10. {
  11. this.m_data = new T[size];
  12. this.m_gch = GCHandle.Alloc(this.m_data, GCHandleType.Pinned);
  13. }
  14. public PinnedArray(T[] data, bool clone = false)
  15. {
  16. this.m_data = ((!clone) ? data : ((T[])data.Clone()));
  17. this.m_gch = GCHandle.Alloc(this.m_data, GCHandleType.Pinned);
  18. }
  19. public int Length
  20. {
  21. get
  22. {
  23. return this.m_data.Length;
  24. }
  25. }
  26. public T this[int i]
  27. {
  28. get
  29. {
  30. return this.m_data[i];
  31. }
  32. set
  33. {
  34. this.m_data[i] = value;
  35. }
  36. }
  37. public T[] Array
  38. {
  39. get
  40. {
  41. return this.m_data;
  42. }
  43. }
  44. public IntPtr Pointer
  45. {
  46. get
  47. {
  48. return (this.m_data.Length != 0) ? this.m_gch.AddrOfPinnedObject() : IntPtr.Zero;
  49. }
  50. }
  51. public PinnedArray<T> Clone()
  52. {
  53. return new PinnedArray<T>((T[])this.m_data.Clone(), false);
  54. }
  55. public bool Assign(T[] source)
  56. {
  57. if (source != null && this.m_data.Length == source.Length)
  58. {
  59. System.Array.Copy(source, this.m_data, this.m_data.Length);
  60. return true;
  61. }
  62. return false;
  63. }
  64. public void Dispose()
  65. {
  66. this.Dispose(true);
  67. GC.SuppressFinalize(this);
  68. }
  69. protected virtual void Dispose(bool disposing)
  70. {
  71. if (disposing && this.m_gch.IsAllocated)
  72. {
  73. this.m_gch.Free();
  74. }
  75. }
  76. public IEnumerator<T> GetEnumerator()
  77. {
  78. return (IEnumerator<T>)this.m_data.GetEnumerator();
  79. }
  80. IEnumerator IEnumerable.GetEnumerator()
  81. {
  82. return this.GetEnumerator();
  83. }
  84. public static implicit operator IntPtr(PinnedArray<T> v)
  85. {
  86. return (v != null) ? v.Pointer : IntPtr.Zero;
  87. }
  88. public static implicit operator T[](PinnedArray<T> v)
  89. {
  90. return (v != null) ? v.Array : null;
  91. }
  92. private T[] m_data;
  93. private GCHandle m_gch;
  94. }
  95. }