CryptoPoolLease
using System.Runtime.CompilerServices;
namespace System.Security.Cryptography
{
internal ref struct CryptoPoolLease : IDisposable
{
private byte[] _rented;
private bool _skipClear;
internal Span<byte> Span {
[System.Runtime.CompilerServices.IsReadOnly]
get;
private set;
}
internal bool IsRented {
[System.Runtime.CompilerServices.IsReadOnly]
get {
return _rented != null;
}
}
public void Dispose()
{
Return();
}
internal void Return()
{
Return((!_skipClear) ? Span.Length : 0);
}
private void Return(int clearSize)
{
if (_rented != null) {
System.Security.Cryptography.CryptoPool.Return(_rented, clearSize);
_rented = null;
} else if (!_skipClear && clearSize > 0) {
Span.Slice(0, clearSize).Clear();
}
Span = default(Span<byte>);
}
internal static CryptoPoolLease Rent(int length, bool skipClear = false)
{
byte[] array = System.Security.Cryptography.CryptoPool.Rent(length);
CryptoPoolLease result = default(CryptoPoolLease);
result._rented = array;
result._skipClear = skipClear;
result.Span = new Span<byte>(array, 0, length);
return result;
}
internal static CryptoPoolLease RentConditionally(int length, Span<byte> currentBuffer, bool skipClear = false, bool skipClearIfNotRented = false)
{
bool rented;
return RentConditionally(length, currentBuffer, out rented, skipClear, skipClearIfNotRented);
}
internal static CryptoPoolLease RentConditionally(int length, Span<byte> currentBuffer, out bool rented, bool skipClear = false, bool skipClearIfNotRented = false)
{
if (currentBuffer.Length >= length) {
rented = false;
CryptoPoolLease result = default(CryptoPoolLease);
result._rented = null;
result._skipClear = (skipClearIfNotRented | skipClear);
result.Span = currentBuffer.Slice(0, length);
return result;
}
rented = true;
return Rent(length, skipClear);
}
}
}