1- // ReSharper disable MemberCanBeInternal
1+ /*
2+ * COPYRIGHT: See COPYING in the top level directory
3+ * PROJECT: ExtendedSystemObjects
4+ * FILE: ExtendedSystemObjects/IUnmanagedArray.cs
5+ * PURPOSE: A high-performance array implementation with reduced features. Limited to unmanaged Types, very similiar to IntArray.
6+ * PROGRAMMER: Peter Geinitz (Wayfarer)
7+ */
8+
9+ // ReSharper disable MemberCanBeInternal
210
311using System ;
412using System . Runtime . InteropServices ;
@@ -13,22 +21,48 @@ namespace ExtendedSystemObjects
1321 /// <seealso cref="T:System.IDisposable" />
1422 public sealed unsafe class UnmanagedArray < T > : IUnmanagedArray < T > where T : unmanaged
1523 {
24+ /// <summary>
25+ /// The buffer
26+ /// </summary>
1627 private IntPtr _buffer ;
28+
29+ /// <summary>
30+ /// The pointer
31+ /// </summary>
1732 private T * _ptr ;
1833
34+ /// <summary>
35+ /// The capacity
36+ /// </summary>
37+ private int _capacity ;
38+
39+
40+ /// <summary>
41+ /// The disposed
42+ /// </summary>
43+ private bool _disposed ;
44+
45+ /// <summary>
46+ /// Gets the length.
47+ /// </summary>
48+ /// <value>
49+ /// The length.
50+ /// </value>
51+ public int Length { get ; private set ; }
52+
1953 /// <summary>
2054 /// Initializes a new instance of the <see cref="UnmanagedArray{T}" /> class.
2155 /// </summary>
2256 /// <param name="size">The size.</param>
2357 public UnmanagedArray ( int size )
2458 {
59+ _capacity = size ;
2560 Length = size ;
2661 _buffer = Marshal . AllocHGlobal ( size * sizeof ( T ) ) ;
2762 _ptr = ( T * ) _buffer ;
63+ Clear ( ) ;
2864 }
2965
30- public int Length { get ; private set ; }
31-
3266 /// <summary>
3367 /// Gets or sets the <see cref="T" /> at the specified index.
3468 /// </summary>
@@ -62,7 +96,6 @@ public T this[int index]
6296 }
6397 }
6498
65-
6699 /// <summary>
67100 /// Resizes the internal array to the specified new size.
68101 /// Contents will be preserved up to the minimum of old and new size.
@@ -72,7 +105,9 @@ public void Resize(int newSize)
72105 {
73106 _buffer = Marshal . ReAllocHGlobal ( _buffer , ( IntPtr ) ( newSize * sizeof ( T ) ) ) ;
74107 _ptr = ( T * ) _buffer ;
75- Length = newSize ;
108+ _capacity = newSize ;
109+ if ( Length > newSize )
110+ Length = newSize ;
76111 }
77112
78113 /// <summary>
@@ -84,20 +119,71 @@ public void Clear()
84119 AsSpan ( ) . Clear ( ) ;
85120 }
86121
122+ /// <summary>
123+ /// Ensures the capacity.
124+ /// </summary>
125+ /// <param name="minCapacity">The minimum capacity.</param>
126+ public void EnsureCapacity ( int minCapacity )
127+ {
128+ if ( minCapacity <= _capacity )
129+ return ;
130+
131+ int newCapacity = _capacity == 0 ? 4 : _capacity ;
132+ while ( newCapacity < minCapacity )
133+ newCapacity *= 2 ;
134+
135+ Resize ( newCapacity ) ;
136+ }
137+
138+ /// <summary>
139+ /// Ases the span.
140+ /// </summary>
141+ /// <returns>Return all Values as Span</returns>
142+ public Span < T > AsSpan ( )
143+ {
144+ return new ( _ptr , Length ) ;
145+ }
146+
147+ /// <summary>
148+ /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
149+ /// </summary>
87150 public void Dispose ( )
88151 {
152+ Dispose ( true ) ;
153+ GC . SuppressFinalize ( this ) ;
154+ }
155+
156+ /// <summary>
157+ /// Finalizes an instance of the <see cref="UnmanagedArray{T}"/> class.
158+ /// </summary>
159+ ~ UnmanagedArray ( )
160+ {
161+ Dispose ( false ) ;
162+ }
163+
164+ /// <summary>
165+ /// Releases unmanaged and - optionally - managed resources.
166+ /// </summary>
167+ /// <param name="disposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
168+ private void Dispose ( bool disposing )
169+ {
170+ if ( _disposed )
171+ return ;
172+
173+ // Only unmanaged cleanup here.
89174 if ( _buffer != IntPtr . Zero )
90175 {
91176 Marshal . FreeHGlobal ( _buffer ) ;
92177 _buffer = IntPtr . Zero ;
93178 _ptr = null ;
94179 Length = 0 ;
180+ _capacity = 0 ;
95181 }
96- }
97182
98- public Span < T > AsSpan ( )
99- {
100- return new ( _ptr , Length ) ;
183+ _disposed = true ;
184+
185+ // 'disposing' parameter unused but required by pattern.
186+ _ = disposing ;
101187 }
102188 }
103189}
0 commit comments