11#nullable enable
2- using System ;
2+ using System ;
3+ using System . Buffers ;
34using System . Buffers . Binary ;
45using System . Diagnostics ;
56
@@ -12,14 +13,15 @@ namespace Renci.SshNet.Sftp.Requests
1213 /// [Sftp packet length, SftpMessageType, RequestId, Handle length, Handle, Server offset, data length, data].
1314 /// [ 4, 1, 4, 4, ?, 8, 4, ?].
1415 /// </remarks>
15- internal sealed class SftpWriteRequestBuffer
16+ internal sealed class SftpWriteRequestBuffer : IDisposable
1617 {
1718 private const int MessageTypeOffset = 4 ;
1819 private const int RequestIdOffset = MessageTypeOffset + 1 ;
1920 private const int HandleLengthOffset = RequestIdOffset + 4 ;
2021 private const int HandleOffset = HandleLengthOffset + 4 ;
2122
22- private readonly byte [ ] _buffer ;
23+ private readonly bool _usePool ;
24+ private byte [ ] _buffer ;
2325
2426 public ArraySegment < byte > ActiveBytes
2527 {
@@ -29,11 +31,17 @@ public ArraySegment<byte> ActiveBytes
2931 }
3032 }
3133
32- public SftpWriteRequestBuffer ( ReadOnlySpan < byte > handle , int dataCapacity )
34+ public SftpWriteRequestBuffer ( ReadOnlySpan < byte > handle , int dataCapacity , bool usePool = false )
3335 {
3436 Debug . Assert ( dataCapacity >= 0 ) ;
3537
36- _buffer = new byte [ HandleOffset + handle . Length + 8 + 4 + dataCapacity ] ;
38+ var totalCapacity = HandleOffset + handle . Length + 8 + 4 + dataCapacity ;
39+
40+ _usePool = usePool ;
41+
42+ _buffer = usePool
43+ ? ArrayPool < byte > . Shared . Rent ( totalCapacity )
44+ : new byte [ totalCapacity ] ;
3745
3846 _buffer [ MessageTypeOffset ] = ( byte ) SftpMessageTypes . Write ;
3947
@@ -42,8 +50,8 @@ public SftpWriteRequestBuffer(ReadOnlySpan<byte> handle, int dataCapacity)
4250 handle . CopyTo ( _buffer . AsSpan ( HandleOffset ) ) ;
4351 }
4452
45- public SftpWriteRequestBuffer ( ReadOnlySpan < byte > handle , ulong serverFileOffset , ReadOnlySpan < byte > data )
46- : this ( handle , data . Length )
53+ public SftpWriteRequestBuffer ( ReadOnlySpan < byte > handle , ulong serverFileOffset , ReadOnlySpan < byte > data , bool usePool = false )
54+ : this ( handle , data . Length , usePool )
4755 {
4856 ServerFileOffset = serverFileOffset ;
4957
@@ -123,5 +131,19 @@ public ArraySegment<byte> Data
123131 return new ArraySegment < byte > ( _buffer , offset , _buffer . Length - offset ) ;
124132 }
125133 }
134+
135+ public void Dispose ( )
136+ {
137+ if ( _usePool )
138+ {
139+ var buffer = _buffer ;
140+ _buffer = null ! ;
141+
142+ if ( buffer is not null )
143+ {
144+ ArrayPool < byte > . Shared . Return ( buffer ) ;
145+ }
146+ }
147+ }
126148 }
127149}
0 commit comments