public override Task WriteAsync(byte[] bytes, int offset, int count) { if (offset < 0) { throw new ArgumentOutOfRangeException(nameof(offset)); } if (count < 0) { throw new ArgumentOutOfRangeException(nameof(count)); } return(DecoratedClient.WriteAsync(EncryptionServiceProvider.Crypt(bytes, offset, count), offset, count)); }
public override async Task WriteAsync(byte[] bytes, int offset, int count) { if (offset < 0) { throw new ArgumentOutOfRangeException(nameof(offset)); } if (count < 0) { throw new ArgumentOutOfRangeException(nameof(count)); } int blocksizeAdjustedCount = ConvertToBlocksizeCount(count); if (count == blocksizeAdjustedCount) { await DecoratedClient.WriteAsync(EncryptionServiceProvider.Crypt(bytes, offset, count), offset, count) .ConfigureAwait(false); } else { //Lock because we use the crypto buffer for this using (await WriteBuffer.BufferLock.LockAsync().ConfigureAwait(false)) { try { //We copy to the thread local buffer so we can use it as an extended buffer by "neededBytes" many more bytes. //So the buffer is very large but we'll tell it to write bytes.length + neededBytes. BufferUtil.QuickUnsafeCopy(bytes, offset, WriteBuffer.Buffer, 0, count); //dont copy full array, might only need less with count } catch (Exception e) { throw new InvalidOperationException($"Failed to copy bytes to crypto buffer. Bytes Length: {bytes.Length} Offset: {offset} Count: {count} BlocksizeAdjustedCount: {blocksizeAdjustedCount}", e); } EncryptionServiceProvider.Crypt(WriteBuffer.Buffer, 0, blocksizeAdjustedCount); //recurr to write the bytes with the now properly sized buffer. await DecoratedClient.WriteAsync(WriteBuffer.Buffer, 0, blocksizeAdjustedCount) .ConfigureAwait(false); } } }