/// <summary> /// Retrieve a new <c>MemoryStream</c> object with the contents unzipped and copied from the provided /// stream. The provided stream is optionally closed. /// </summary> /// <remarks>The new stream's position is set to the beginning of the stream when returned.</remarks> /// <param name="data"></param> /// <param name="leaveStreamOpen"></param> /// <returns></returns> public async ValueTask <MemoryStream> CompressAsync(Stream inputStream, bool leaveStreamOpen = false) { Guard.AgainstNullOrEmpty(inputStream, nameof(inputStream)); if (inputStream.Position == inputStream.Length) { inputStream.Seek(0, SeekOrigin.Begin); } var compressedStream = RecyclableManager.GetStream(nameof(RecyclableGzipProvider)); using (var gzipStream = new GZipStream(compressedStream, CompressionLevel, true)) { await inputStream .CopyToAsync(gzipStream) .ConfigureAwait(false); } if (!leaveStreamOpen) { inputStream.Close(); } compressedStream.Seek(0, SeekOrigin.Begin); return(compressedStream); }
public async ValueTask <ArraySegment <byte> > CompressAsync(ReadOnlyMemory <byte> inputData) { Guard.AgainstEmpty(inputData, nameof(inputData)); var compressedStream = RecyclableManager.GetStream(nameof(RecyclableGzipProvider)); using (var gzipStream = new GZipStream(compressedStream, CompressionLevel, true)) { await gzipStream .WriteAsync(inputData) .ConfigureAwait(false); } if (compressedStream.TryGetBuffer(out var buffer)) { return(buffer); } else { using (compressedStream) // dispose stream after allocation. { return(compressedStream.ToArray()); } } }
public async ValueTask <ArraySegment <byte> > DecompressAsync(ReadOnlyMemory <byte> compressedData) { Guard.AgainstEmpty(compressedData, nameof(compressedData)); using var uncompressedStream = RecyclableManager.GetStream(nameof(RecyclableGzipProvider), CompressionHelpers.GetGzipUncompressedLength(compressedData)); using (var gzipStream = new GZipStream(compressedData.AsStream(), CompressionMode.Decompress, false)) { await gzipStream .CopyToAsync(uncompressedStream) .ConfigureAwait(false); } if (uncompressedStream.TryGetBuffer(out var buffer)) { return(buffer); } else { // dispose stream after allocation. using (uncompressedStream) { return(uncompressedStream.ToArray()); } } }
public void Middleware_Input2 <TIn>(TIn input) { using var serializedStream = RecyclableManager.GetStream(nameof(RecyclableTransformer)); _middleware.SerializationProvider.Serialize(serializedStream, input); using var compressedStream = _middleware.CompressionProvider.Compress(serializedStream, false); var encryptedStream = _middleware.EncryptionProvider.Encrypt(compressedStream, false); }
public MemoryStream Encrypt(MemoryStream unencryptedStream, bool leaveStreamOpen = false) { Guard.AgainstNullOrEmpty(unencryptedStream, nameof(unencryptedStream)); using var aes = new AesGcm(_key.Span); var length = (int)unencryptedStream.Length; (var buffer, var returnBuffer) = unencryptedStream.GetSafeBuffer(length); // Slicing Version // Rented arrays sizes are minimums, not guarantees. // Need to perform extra work managing slices to keep the byte sizes correct but the memory allocations are lower by 200% var encryptedBytes = _pool.Rent(length); var tag = _pool.Rent(AesGcm.TagByteSizes.MaxSize); // MaxSize = 16 var nonce = _pool.Rent(AesGcm.NonceByteSizes.MaxSize); // MaxSize = 12 _rng.GetBytes(nonce, 0, AesGcm.NonceByteSizes.MaxSize); aes.Encrypt( nonce.AsSpan().Slice(0, AesGcm.NonceByteSizes.MaxSize), buffer.AsSpan().Slice(0, length), encryptedBytes.AsSpan().Slice(0, length), tag.AsSpan().Slice(0, AesGcm.TagByteSizes.MaxSize)); // Prefix ciphertext with nonce and tag, since they are fixed length and it will simplify decryption. // Our pattern: Nonce Tag Cipher // Other patterns people use: Nonce Cipher Tag // couldn't find a solid source. var encryptedStream = RecyclableManager.GetStream( nameof(RecyclableAesGcmEncryptionProvider), AesGcm.NonceByteSizes.MaxSize + AesGcm.TagByteSizes.MaxSize + length); using (var binaryWriter = new BinaryWriter(encryptedStream, Encoding.UTF8, true)) { binaryWriter.Write(nonce, 0, AesGcm.NonceByteSizes.MaxSize); binaryWriter.Write(tag, 0, AesGcm.TagByteSizes.MaxSize); binaryWriter.Write(encryptedBytes, 0, length); } if (returnBuffer) { _pool.Return(buffer.Array); } _pool.Return(encryptedBytes); _pool.Return(tag); _pool.Return(nonce); encryptedStream.Seek(0, SeekOrigin.Begin); if (!leaveStreamOpen) { unencryptedStream.Close(); } return(encryptedStream); }
/// <summary> /// Returns a new <c>MemoryStream</c> that has decompressed data inside. /// </summary> /// <param name="compressedStream"></param> /// <param name="leaveStreamOpen"></param> /// <returns>A <c>new MemoryStream</c>.</returns> public MemoryStream DecompressToStream(ReadOnlyMemory <byte> compressedData) { Guard.AgainstEmpty(compressedData, nameof(compressedData)); var uncompressedStream = RecyclableManager.GetStream(nameof(RecyclableBrotliProvider)); using (var brotliStream = new BrotliStream(compressedData.AsStream(), CompressionMode.Decompress, false)) { brotliStream.CopyTo(uncompressedStream); } return(uncompressedStream); }
/// <summary> /// Returns a new <c>MemoryStream</c> that has decompressed data inside. /// </summary> /// <param name="compressedStream"></param> /// <param name="leaveStreamOpen"></param> /// <returns>A <c>new MemoryStream</c>.</returns> public MemoryStream DecompressToStream(ReadOnlyMemory <byte> compressedData) { Guard.AgainstEmpty(compressedData, nameof(compressedData)); var uncompressedStream = RecyclableManager.GetStream(nameof(RecyclableGzipProvider), CompressionHelpers.GetGzipUncompressedLength(compressedData)); using (var gzipStream = new GZipStream(compressedData.AsStream(), CompressionMode.Decompress, false)) { gzipStream.CopyTo(uncompressedStream); } return(uncompressedStream); }
/// <summary> /// Retrieve a new <c>MemoryStream</c> object with the contents contained zipped data writen from the unzipped /// bytes in <c>ReadOnlyMemory<byte></c>. /// </summary> /// <remarks>The new stream's position is set to the beginning of the stream when returned.</remarks> /// <param name="data"></param> /// <returns></returns> public MemoryStream CompressToStream(ReadOnlyMemory <byte> inputData) { Guard.AgainstEmpty(inputData, nameof(inputData)); var compressedStream = RecyclableManager.GetStream(nameof(RecyclableGzipProvider)); using (var gzipStream = new GZipStream(compressedStream, CompressionLevel, true)) { gzipStream.Write(inputData.Span); } compressedStream.Seek(0, SeekOrigin.Begin); return(compressedStream); }
/// <summary> /// Retrieve a new <c>MemoryStream</c> object with the contents contained zipped data writen from the unzipped /// bytes in <c>ReadOnlyMemory<byte></c>. /// </summary> /// <remarks>The new stream's position is set to the beginning of the stream when returned.</remarks> /// <param name="data"></param> /// <returns></returns> public async ValueTask <MemoryStream> CompressToStreamAsync(ReadOnlyMemory <byte> inputData) { Guard.AgainstEmpty(inputData, nameof(inputData)); var compressedStream = RecyclableManager.GetStream(nameof(RecyclableGzipProvider)); using (var gzipStream = new GZipStream(compressedStream, CompressionLevel, true)) { await gzipStream .WriteAsync(inputData) .ConfigureAwait(false); } compressedStream.Seek(0, SeekOrigin.Begin); return(compressedStream); }
/// <summary> /// Returns a new MemoryStream() that has decompressed data inside. Original stream is closed/disposed. /// <para>Use <c>RecyclableManager.ReturnStream()</c> to return the <c>MemoryStream</c> when you are ready to dispose of it.</para> /// </summary> /// <param name="compressedStream"></param> /// <param name="leaveStreamOpen"></param> /// <returns></returns> public MemoryStream Decompress(Stream compressedStream, bool leaveStreamOpen = false) { Guard.AgainstNullOrEmpty(compressedStream, nameof(compressedStream)); if (compressedStream.Position == compressedStream.Length) { compressedStream.Seek(0, SeekOrigin.Begin); } var uncompressedStream = RecyclableManager.GetStream(nameof(RecyclableGzipProvider), CompressionHelpers.GetGzipUncompressedLength(compressedStream)); using (var gzipStream = new GZipStream(compressedStream, CompressionMode.Decompress, leaveStreamOpen)) { gzipStream.CopyTo(uncompressedStream); } return(uncompressedStream); }
/// <summary> /// Returns a new <c>MemoryStream</c> that has decompressed data inside. The provided stream is optionally closed. /// </summary> /// <param name="compressedStream"></param> /// <param name="leaveStreamOpen"></param> /// <returns></returns> public async ValueTask <MemoryStream> DecompressAsync(Stream compressedStream, bool leaveStreamOpen = false) { Guard.AgainstNullOrEmpty(compressedStream, nameof(compressedStream)); if (compressedStream.Position == compressedStream.Length) { compressedStream.Seek(0, SeekOrigin.Begin); } var uncompressedStream = RecyclableManager.GetStream(nameof(RecyclableBrotliProvider)); using (var brotliStream = new BrotliStream(compressedStream, CompressionMode.Decompress, leaveStreamOpen)) { await brotliStream .CopyToAsync(uncompressedStream) .ConfigureAwait(false); } return(uncompressedStream); }
public ArraySegment <byte> Compress(ReadOnlyMemory <byte> inputData) { Guard.AgainstEmpty(inputData, nameof(inputData)); var compressedStream = RecyclableManager.GetStream(nameof(RecyclableGzipProvider)); using (var gzipStream = new GZipStream(compressedStream, CompressionLevel, true)) { gzipStream.Write(inputData.Span); } if (compressedStream.TryGetBuffer(out var buffer)) { return(buffer); } else { using (compressedStream) // dispose stream after allocation. { return(compressedStream.ToArray()); } } }
/// <summary> /// Retrieve a new <c>MemoryStream</c> object with the contents unzipped and copied from the provided /// stream. The provided stream is optionally closed. /// </summary> /// <remarks>The new stream's position is set to the beginning of the stream when returned.</remarks> /// <param name="data"></param> /// <param name="leaveStreamOpen"></param> /// <returns></returns> public MemoryStream Compress(Stream inputStream, bool leaveStreamOpen = false) { Guard.AgainstNullOrEmpty(inputStream, nameof(inputStream)); if (inputStream.Position == inputStream.Length) { inputStream.Seek(0, SeekOrigin.Begin); } var compressedStream = RecyclableManager.GetStream(nameof(RecyclableBrotliProvider)); using (var brotliStream = new BrotliStream(compressedStream, CompressionLevel, true)) { inputStream.CopyTo(brotliStream); } if (!leaveStreamOpen) { inputStream.Close(); } compressedStream.Seek(0, SeekOrigin.Begin); return(compressedStream); }
public ArraySegment <byte> Decompress(ReadOnlyMemory <byte> compressedData) { Guard.AgainstEmpty(compressedData, nameof(compressedData)); var uncompressedStream = RecyclableManager.GetStream(nameof(RecyclableBrotliProvider)); using (var brotliStream = new BrotliStream(compressedData.AsStream(), CompressionMode.Decompress, false)) { brotliStream.CopyTo(uncompressedStream); } if (uncompressedStream.TryGetBuffer(out var buffer)) { return(buffer); } else { // dispose stream after allocation. using (uncompressedStream) { return(uncompressedStream.ToArray()); } } }
public void Middleware_Input1 <TIn>(TIn input) { using var serializedStream = RecyclableManager.GetStream(nameof(RecyclableTransformer)); _middleware.SerializationProvider.Serialize(serializedStream, input); }
public MemoryStream DecryptToStream(ReadOnlyMemory <byte> encryptedData) { Guard.AgainstEmpty(encryptedData, nameof(encryptedData)); return(RecyclableManager.GetStream(nameof(RecyclableAesGcmEncryptionProvider), Decrypt(encryptedData))); }
public MemoryStream Decrypt(MemoryStream encryptedStream, bool leaveStreamOpen = false) { Guard.AgainstNullOrEmpty(encryptedStream, nameof(encryptedStream)); if (encryptedStream.Position == encryptedStream.Length) { encryptedStream.Seek(0, SeekOrigin.Begin); } using var aes = new AesGcm(_key.Span); var encryptedByteLength = (int)encryptedStream.Length - AesGcm.NonceByteSizes.MaxSize - AesGcm.TagByteSizes.MaxSize; var encryptedBufferBytes = _pool.Rent(encryptedByteLength); var tagBytes = _pool.Rent(AesGcm.TagByteSizes.MaxSize); var nonceBytes = _pool.Rent(AesGcm.NonceByteSizes.MaxSize); var bytesRead = encryptedStream.Read(nonceBytes, 0, AesGcm.NonceByteSizes.MaxSize); if (bytesRead == 0) { throw new InvalidDataException(); } bytesRead = encryptedStream.Read(tagBytes, 0, AesGcm.TagByteSizes.MaxSize); if (bytesRead == 0) { throw new InvalidDataException(); } bytesRead = encryptedStream.Read(encryptedBufferBytes, 0, encryptedByteLength); if (bytesRead == 0) { throw new InvalidDataException(); } // Slicing Version var nonce = nonceBytes .AsSpan() .Slice(0, AesGcm.NonceByteSizes.MaxSize); var tag = tagBytes .AsSpan() .Slice(0, AesGcm.TagByteSizes.MaxSize); var encryptedBytes = encryptedBufferBytes .AsSpan() .Slice(0, encryptedByteLength); var decryptedBytes = new byte[encryptedByteLength]; aes.Decrypt(nonce, encryptedBytes, tag, decryptedBytes); _pool.Return(encryptedBufferBytes); _pool.Return(tagBytes); _pool.Return(nonceBytes); if (!leaveStreamOpen) { encryptedStream.Close(); } return(RecyclableManager.GetStream(nameof(RecyclableAesGcmEncryptionProvider), decryptedBytes)); }