@@ -14,45 +14,42 @@ You may obtain a copy of the License at
1414 limitations under the License.
1515******************************************************************************/
1616
17+ using NumSharp . Backends . Unmanaged ;
1718using System ;
1819using System . Runtime . CompilerServices ;
1920using System . Runtime . InteropServices ;
20- using NumSharp . Backends . Unmanaged ;
21+ using Tensorflow . Util ;
2122using static Tensorflow . c_api ;
2223
2324namespace Tensorflow
2425{
2526 /// <summary>
2627 /// Represents a TF_Buffer that can be passed to Tensorflow.
2728 /// </summary>
28- public class Buffer : DisposableObject
29+ public sealed class Buffer : IDisposable
2930 {
30- private unsafe TF_Buffer buffer
31- {
32- [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
33- get => * bufferptr ;
34- }
31+ public SafeBufferHandle Handle { get ; }
3532
36- private unsafe TF_Buffer * bufferptr
37- {
38- [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
39- get => ( TF_Buffer * ) _handle ;
40- }
33+ /// <remarks>
34+ /// <inheritdoc cref="SafeHandleLease" path="/devdoc/usage"/>
35+ /// </remarks>
36+ private unsafe ref readonly TF_Buffer DangerousBuffer
37+ => ref Unsafe . AsRef < TF_Buffer > ( Handle . DangerousGetHandle ( ) . ToPointer ( ) ) ;
4138
4239 /// <summary>
4340 /// The memory block representing this buffer.
4441 /// </summary>
45- /// <remarks>The deallocator is set to null.</remarks>
46- public UnmanagedMemoryBlock < byte > MemoryBlock
42+ /// <remarks>
43+ /// <para>The deallocator is set to null.</para>
44+ ///
45+ /// <inheritdoc cref="SafeHandleLease" path="/devdoc/usage"/>
46+ /// </remarks>
47+ public unsafe UnmanagedMemoryBlock < byte > DangerousMemoryBlock
4748 {
4849 get
4950 {
50- unsafe
51- {
52- EnsureNotDisposed ( ) ;
53- var buff = ( TF_Buffer * ) _handle ;
54- return new UnmanagedMemoryBlock < byte > ( ( byte * ) buff ->data . ToPointer ( ) , ( long ) buff ->length ) ;
55- }
51+ ref readonly TF_Buffer buffer = ref DangerousBuffer ;
52+ return new UnmanagedMemoryBlock < byte > ( ( byte * ) buffer . data . ToPointer ( ) , ( long ) buffer . length ) ;
5653 }
5754 }
5855
@@ -63,25 +60,23 @@ public ulong Length
6360 {
6461 get
6562 {
66- EnsureNotDisposed ( ) ;
67- return buffer . length ;
63+ using ( Handle . Lease ( ) )
64+ {
65+ return DangerousBuffer . length ;
66+ }
6867 }
6968 }
7069
71- public Buffer ( ) => _handle = TF_NewBuffer ( ) ;
72-
73- public Buffer ( IntPtr handle )
74- {
75- if ( handle == IntPtr . Zero )
76- throw new ArgumentException ( "Handle (IntPtr) can't be zero." , nameof ( handle ) ) ;
70+ public Buffer ( )
71+ => Handle = TF_NewBuffer ( ) ;
7772
78- _handle = handle ;
79- }
73+ public Buffer ( SafeBufferHandle handle )
74+ => Handle = handle ;
8075
81- public Buffer ( byte [ ] data ) : this ( _toBuffer ( data ) )
82- { }
76+ public Buffer ( byte [ ] data )
77+ => Handle = _toBuffer ( data ) ;
8378
84- private static IntPtr _toBuffer ( byte [ ] data )
79+ private static SafeBufferHandle _toBuffer ( byte [ ] data )
8580 {
8681 if ( data == null )
8782 throw new ArgumentNullException ( nameof ( data ) ) ;
@@ -93,38 +88,25 @@ private static IntPtr _toBuffer(byte[] data)
9388 }
9489 }
9590
96- public static implicit operator IntPtr ( Buffer buffer )
97- {
98- buffer . EnsureNotDisposed ( ) ;
99- return buffer . _handle ;
100- }
101-
102- public static explicit operator byte [ ] ( Buffer buffer ) => buffer . ToArray ( ) ; //has to be explicit, developer will assume it doesn't cost.
103-
10491 /// <summary>
10592 /// Copies this buffer's contents onto a <see cref="byte"/> array.
10693 /// </summary>
10794 public byte [ ] ToArray ( )
10895 {
109- EnsureNotDisposed ( ) ;
110-
111- unsafe
96+ using ( Handle . Lease ( ) )
11297 {
113- var len = buffer . length ;
98+ var block = DangerousMemoryBlock ;
99+ var len = block . Count ;
114100 if ( len == 0 )
115101 return Array . Empty < byte > ( ) ;
116102
117- byte [ ] data = new byte [ len ] ;
118- fixed ( byte * dst = data )
119- System . Buffer . MemoryCopy ( ( void * ) bufferptr ->data , dst , len , len ) ;
120-
103+ var data = new byte [ len ] ;
104+ block . CopyTo ( data , 0 ) ;
121105 return data ;
122106 }
123107 }
124108
125- protected override void DisposeUnmanagedResources ( IntPtr handle )
126- {
127- TF_DeleteBuffer ( handle ) ;
128- }
109+ public void Dispose ( )
110+ => Handle . Dispose ( ) ;
129111 }
130112}
0 commit comments