Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Span-based (non-stream) compression APIs #39327

Open
timmydo opened this issue Jul 14, 2020 · 3 comments
Open

Span-based (non-stream) compression APIs #39327

timmydo opened this issue Jul 14, 2020 · 3 comments
Labels
api-suggestion Early API idea and discussion, it is NOT ready for implementation area-System.IO.Compression needs-further-triage Issue has been initially triaged, but needs deeper consideration or reconsideration
Milestone

Comments

@timmydo
Copy link

timmydo commented Jul 14, 2020

Background and Motivation

Currently to compress/decompress in .NET, you typically would use GZipStream or DeflateStream. However, there are a lot of times where you have an array of bytes and you want to get your output in an array of bytes. It would be simpler/faster to not have to have a bunch of stream redirection to the underlying byte array.

The request is that we add some methods that operate on bytes.

Proposed API

Roughly something like this

namespace System.IO.Compression
{
public class GZipCompressor
public class DeflateCompressor
{
 private object state;
 public ctor(CompressionLevel)
 public void Compress(ReadOnlySpan<byte> in, Span<byte> out, enum flushType, out uint outputBytesWritten);
}
}

Usage Examples

I'm just sort of pseudo-coding this out:

var input = new List<byte[]> {...};
var output = ArrayPool.Shared.Rent(GetMaxCompressedSize(input.Sum(x => x.Length)));
var compressor = new GZipCompressor(CompressionLevel.Optimal);
var outputIndex = 0;
foreach (var array in input)
{
compressor.Compress(new ReadOnlySpan<byte>(array), new Span<byte>(output, outputIndex, output.Length - outputIndex), Z.NoFlush, out var written)
outputIndex += written;
}

compressor.Compress(default(), new Span<byte>(output, outputIndex, output.Length - outputIndex, Z.FinalFlush, out var finalWrite);

 var finalOutput = new Span<byte>(output, 0, outputIndex + finalWrite);
// do stuff with finalOutput

}
@timmydo timmydo added the api-suggestion Early API idea and discussion, it is NOT ready for implementation label Jul 14, 2020
@Dotnet-GitSync-Bot Dotnet-GitSync-Bot added area-System.IO.Compression untriaged New issue has not been triaged by the area owner labels Jul 14, 2020
@scalablecory scalablecory changed the title Request for low-level compression APIs Span-based (non-stream) compression APIs Jul 15, 2020
@FiniteReality
Copy link

FiniteReality commented Jul 15, 2020

These should probably use the OperationStatus enum to communicate its result, like the BrotliEncoder/Decoder. The names should also follow suit. So, something like this would make sense for DEFLATE, I believe:

class DeflateEncoder : IDisposable
{
    public DeflateEncoder(CompressionLevel level);
    public OperationStatus Compress(ReadOnlySpan<byte> source, ReadOnlySpan<byte> destination, out int bytesConsumed, out int bytesWritten, bool isFinalBlock);
    public static int GetMaxCompressedLength(int inputSize);
    // IDisposable implementation
}
class DeflateDecoder : IDisposable
{
    public DeflateDecoder(CompressionLevel level);
    public OperationStatus Decompress(ReadOnlySpan<byte> source, ReadOnlySpan<byte> destination, out int bytesConsumed, out int bytesWritten, bool isFinalBlock);
    // IDisposable implementation
}

// Likewise for GZip

Since we're here, could we potentially also add one for ZLib? It would have the same API as above, but instead of producing raw DEFLATE blocks or GZip blocks, it would produce ZLib blocks instead.

@carlossanlop carlossanlop added this to the Future milestone Aug 6, 2020
@carlossanlop carlossanlop removed the untriaged New issue has not been triaged by the area owner label Aug 17, 2020
@timmydo
Copy link
Author

timmydo commented Sep 15, 2020

Related #16923

@wegylexy
Copy link
Contributor

I read about ZLib compression level was between 0 and 9, but now may be 19 or even higher. Need a way to specify that too.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
api-suggestion Early API idea and discussion, it is NOT ready for implementation area-System.IO.Compression needs-further-triage Issue has been initially triaged, but needs deeper consideration or reconsideration
Projects
None yet
Development

No branches or pull requests

5 participants