Skip to content

[API Proposal]: Add Reset and isFinished to the streamless compression decoders #130465

Description

@iremyux

Background and motivation

.NET 11 introduced the streamless, non-allocating decoders DeflateDecoder, ZLibDecoder, and GZipDecoder. Each holds a native inflate stream and exposes an instance Decompress(...) method plus a static TryDecompress(...) helper.

Once a decoder finishes a stream, the instance latches an internal  _finished  flag. Every subsequent Decompress  call then returns OperationStatus.Done with bytesConsumed == 0 and bytesWritten == 0 , silently doing nothing. This makes the instance effectively one-shot.

This API addresses the reusability limitation reported in #129090.

var decoder = new ZLibDecoder();
decoder.Decompress(streamA, dest, out _, out _); // works
decoder.Decompress(streamB, dest, out _, out _); // silently returns Done, 0/0

Users who want to decode many independent payloads must therefore create and dispose a new decoder for each one, defeating the purpose of the reusable, allocation-conscious instance API (the static TryDecompresy already does create/dispose per call).

API Proposal

namespace System.IO.Compression
{
    public sealed partial class DeflateDecoder : System.IDisposable
    {
        public bool IsFinished { get; }
        public void Reset();
    }

    public sealed partial class ZLibDecoder : System.IDisposable
    {
        public bool IsFinished { get; }
        public void Reset();
    }

    public sealed partial class GZipDecoder : System.IDisposable
    {
        public bool IsFinished { get; }
        public void Reset();
    }
}

API Usage

using var decoder = new ZLibDecoder();

foreach (ReadOnlyMemory<byte> payload in payloads)
{
    OperationStatus status = decoder.Decompress(payload.Span, destination, out int consumed, out int written);
    // ... use destination[..written] ...

    if (decoder.IsFinished)
    {
        decoder.Reset(); // ready for the next independent stream
    }
}

Alternative Designs

No response

Risks

No response

Metadata

Metadata

Assignees

Type

No type

Fields

No fields configured for issues without a type.

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions