true to continue processing, false to request cancellation.
If the provider supports cancellation and the callback returns false, the operation will throw CompressionError with CompressionErrorCode.CANCELLED.
ddn.api.compressor
A robust and flexible compression API for the D programming language.
Design goals (inspired by popular APIs such as zlib, zstd, Brotli, LZ4, Java's java.util.zip, .NET, and Go's compress):
This module defines the API only. Concrete implementations (e.g., GZIP) should live in their own packages/modules and register themselves via the provider registration functions herein.
()Supported container/format kinds (extensible).
Each member denotes exactly one wire format; combinations are expressed by picking the matching container member.
Compression level presets (exact scale is provider/format dependent).
Provider-specific numeric levels beyond these presets are permitted via CompressionOptions.numericLevel.
Compression strategy hint (zlib-style, optional for providers that support it).
Flush mode for streaming compressors (zlib-style semantics).
Checksum type to emit/validate at the container level (when applicable).
Error codes used by CompressionError.
Exception class for compression/decompression related errors.
CompressionErrorCode codeMachine-readable error code carried by this exception.this(string msg, CompressionErrorCode code = CompressionErrorCode.INTERNAL_ERROR,
string file = __FILE__, size_t line = __LINE__,
Throwable next = null)Construct the error.Capabilities declared by a provider for a given format.
These flags describe the behavioral characteristics of a compression provider, allowing users to make informed decisions about memory usage and streaming behavior.
bool streamingbool dictionariesbool multithreadedbool independentBlocksbool buffersAllInputOptions shared by compressors.
CompressionFormat formatCompressionLevel levelCompressionStrategy strategyChecksumType checksumshort numericLevelCompressionProvider-specific numeric level (e.g., zstd 1..22). If < 0, ignored.int windowBitsWindow and block tuning (provider dependent; ignored if unsupported).int blockSizeint threadsStreaming & threading hints.const(ubyte)[] dictionaryOptional dictionary; if empty, not used.size_t progressIntervalBytesMinimum bytes between progress callback invocations (0 = provider default, typically 64 KiB).Options shared by decompressors.
CompressionFormat formatbool autoDetectFormatIf true, decompressor will attempt to auto-detect the format from input.const(ubyte)[] dictionaryOptional dictionary to use (if required/requested by stream).size_t progressIntervalBytesMinimum bytes between progress callback invocations (0 = provider default, typically 64 KiB).size_t maxOutputSizeMaximum total decompressed bytes; `decompressBuffer` aborts with MEMORY_ERROR beyond this limit, guarding against decompression bombs (0 = unlimited).Progress information passed to callbacks during compression/decompression.
This struct provides real-time statistics about the operation's progress, allowing applications to display progress bars, log status, or implement cancellation support.
ulong bytesInTotal bytes consumed so far (uncompressed for compressor, compressed for decompressor)ulong bytesOutTotal bytes produced so far (compressed for compressor, decompressed for decompressor)float ratioCurrent ratio, always `bytesOut / bytesIn` (compression ratio for compressors, expansion factor for decompressors)bool canCancelProgress callback delegate.
Called periodically during write() and finish() operations to report progress. The callback frequency is controlled by progressIntervalBytes in the options.
info | Current progress information |
true to continue processing, false to request cancellation.
If the provider supports cancellation and the callback returns false, the operation will throw CompressionError with CompressionErrorCode.CANCELLED.
Output sink delegate used by streaming interfaces.
Compressor streaming interface (push model).
CompressionOptions options() @property const;Return the options the compressor was created with (may be adjusted by provider).void setOutputSink(OutputSink sink)Set the output sink to receive produced compressed bytes. Must be set before write/flush/finish.void setProgressCallback(ProgressCallback callback)Set an optional progress callback.void write(const(ubyte)[] data)Feed more uncompressed data into the stream.void flush(FlushMode mode = FlushMode.SYNC)Flush pending output according to mode. For finish semantics, prefer finish().void finish()Finalize the stream. After finish() the compressor is closed for further writes.void reset()Reset the stream to initial state (options retained). Output sink remains unchanged.bool setDictionary(const(ubyte)[] dict)Optional: set or update dictionary. Return true if accepted, false if not supported.bool isFinished() @property const;Returns true if finish() has been called and the stream is closed for further writes.Decompressor streaming interface (push model).
DecompressionOptions options() @property const;Return the options the decompressor was created with.void setOutputSink(OutputSink sink)Set the output sink to receive produced decompressed bytes. Must be set before write/finish.void setProgressCallback(ProgressCallback callback)Set an optional progress callback.void write(const(ubyte)[] data)Feed more compressed data into the stream.void finish()Signal end-of-input; allows the decompressor to validate checksums and emit any trailing bytes.void reset()Reset the stream to initial state (options retained). Output sink remains unchanged.bool setDictionary(const(ubyte)[] dict)Optional: provide a dictionary (if required). Return true if accepted or not needed.bool isFinished() @property const;Returns true if finish() has been called and the stream is closed for further writes.Functions used by providers to create new stream instances.
Factory function type for creating decompressors.
CompressionProvider descriptor used for registration.
Each provider is uniquely identified by the combination of vendor and format. The full provider name is constructed as vendor-format (e.g., "ddn-gzip", "ddn-bzip2").
CompressionFormat formatstring vendorVendor identifier for this provider implementation.int priorityFormatCapabilities capsCompressorFactoryFn makeCompressorDecompressorFactoryFn makeDecompressorHeap-allocated buffer holder to avoid delegate capture issues with structs.
When a delegate captures a struct member, it captures a pointer to the struct. If the struct is moved or copied, the pointer becomes invalid. This class provides a stable reference for the output buffer that remains valid across struct moves.
ubyte[] bufferBytes accumulated so far.An input range that lazily compresses data from a source range.
This wraps the existing Compressor interface to provide pull-based semantics. Data is compressed on-demand as the range is iterated.
The source range must yield elements convertible to const(ubyte)[].
SourceRange | The type of the source input range providing uncompressed data chunks. |
private SourceRange _sourceprivate Compressor _compressorprivate const(ubyte)[] _currentOutputprivate OutputBufferHolder _bufferHolderprivate bool _finishedprivate bool _sourceExhaustedvoid popFront()Input range primitive: advance to next element.this(SourceRange source, CompressionOptions opts, string providerName = null)Construct a compression range.this()Disabled default constructor - must be constructed with source and options.An input range that lazily decompresses data from a source range.
This wraps the existing Decompressor interface to provide pull-based semantics. Data is decompressed on-demand as the range is iterated.
The source range must yield elements convertible to const(ubyte)[].
SourceRange | The type of the source input range providing compressed data chunks. |
private SourceRange _sourceprivate Decompressor _decompressorprivate const(ubyte)[] _currentOutputprivate OutputBufferHolder _bufferHolderprivate bool _finishedprivate bool _sourceExhaustedvoid popFront()Input range primitive: advance to next element.this(SourceRange source, DecompressionOptions opts, string providerName = null)Construct a decompression range.this()Disabled default constructor - must be constructed with source and options.An output range that compresses data written to it.
Compressed output is forwarded to a provided sink delegate. This is useful when you want to use range algorithms that write to an output range.
Call finish() when done writing to finalize the compressed stream.
void put(const(ubyte)[] data)Output range primitive: accept data.void finish()Finalize compression. Must be called when done writing.this(OutputSink sink, CompressionOptions opts, string providerName = null)Construct a compression output range.this()Disabled default constructor - must be constructed with sink and options.An output range that decompresses data written to it.
Decompressed output is forwarded to a provided sink delegate. This is useful when you want to use range algorithms that write to an output range.
Call finish() when done writing to finalize the decompressed stream.
void put(const(ubyte)[] data)Output range primitive: accept data.void finish()Finalize decompression. Must be called when done writing.this(OutputSink sink, DecompressionOptions opts, string providerName = null)Construct a decompression output range.this()Disabled default constructor - must be constructed with sink and options.A pass-through compressor used by API-level unittests.
private CompressionOptions _optsprivate void delegate(const(ubyte)[]) _sinkprivate bool _finishedvoid setOutputSink(OutputSink s)void setProgressCallback(ProgressCallback callback)void write(const(ubyte)[] data)void finish()void reset()bool setDictionary(const(ubyte)[] dict)A pass-through decompressor used by API-level unittests.
private DecompressionOptions _optsprivate void delegate(const(ubyte)[]) _sinkprivate bool _finishedvoid setOutputSink(OutputSink s)void setProgressCallback(ProgressCallback callback)void write(const(ubyte)[] data)void finish()void reset()bool setDictionary(const(ubyte)[] dict)void registerProvider(CompressionProvider provider)Register a provider for a given format as specified by `provider.format`.CompressionProvider[] providersFor(CompressionFormat fmt)Query available providers for a format. Returns a copy; mutating it does not affect the registry. Thread-safe.bool tryParseFormatId(string formatId, out CompressionFormat fmt)Internal helper: map a textual format id to a `CompressionFormat`.CompressionProvider[] providersFor(string formatId)Query available providers for a string-identified format. The textual `formatId` is mapped to a `CompressionFormat` and the corresponding enum-based registry entry is returned.CompressionFormat detectFormat(const(ubyte)[] headerBytes)Detect compression format from header bytes.CompressionProvider selectProvider(CompressionFormat fmt, const(char)[] providerName)Pick the best matching provider by format and optional full provider name.CompressionProvider selectProvider(string formatId, const(char)[] providerName)Pick the best matching provider by string formatId and optional full provider name.string formatIdNormalize(string s) pure @safeNormalize a formatId for use as a registry key (lowercase).Compressor makeCompressor(CompressionOptions opts, string providerName = null)Create a streaming compressor for the requested options.Decompressor makeDecompressor(DecompressionOptions opts, string providerName = null)Create a streaming decompressor for the requested options.Compressor makeCompressorById(string formatId, CompressionOptions opts, string providerName = null)Create a streaming compressor for a string-identified custom format.Decompressor makeDecompressorById(string formatId, DecompressionOptions opts, string providerName = null)Create a streaming decompressor for a string-identified custom format.ubyte[] compressBuffer(const(ubyte)[] input,
CompressionOptions opts = CompressionOptions.init,
string providerName = null)Compress a whole buffer in one call.ubyte[] decompressBuffer(const(ubyte)[] input,
DecompressionOptions opts = DecompressionOptions.init,
string providerName = null)Decompress a whole buffer in one call.ubyte[] compressBuffer(CompressionFormat fmt, const(ubyte)[] input, string providerName = null)Convenience: compress a whole buffer with just a format specification.ubyte[] decompressBuffer(CompressionFormat fmt, const(ubyte)[] input, string providerName = null)Convenience: decompress a whole buffer with just a format specification.size_t estimateCompressedSize(CompressionFormat fmt, size_t inputSize) pure nothrow @nogcEstimate the maximum compressed output size for a given input size and format.auto compressRange(Range)(Range source, CompressionOptions opts, string providerName = null) if (isInputRange!Range && is(ElementType!Range : const(ubyte)[]))Convenience function to create a compression range.auto compressRange(Range)(Range source, CompressionFormat fmt) if (isInputRange!Range && is(ElementType!Range : const(ubyte)[]))Convenience overload to create a compression range with just a format.auto decompressRange(Range)(Range source, DecompressionOptions opts, string providerName = null) if (isInputRange!Range && is(ElementType!Range : const(ubyte)[]))Convenience function to create a decompression range.auto decompressRange(Range)(Range source, CompressionFormat fmt) if (isInputRange!Range && is(ElementType!Range : const(ubyte)[]))Convenience overload to create a decompression range with just a format.auto compressOutputRange(OutputSink sink, CompressionOptions opts, string providerName = null)Convenience function to create a compression output range.auto compressOutputRange(OutputSink sink, CompressionFormat fmt)Convenience overload to create a compression output range with just a format.auto decompressOutputRange(OutputSink sink, DecompressionOptions opts, string providerName = null)Convenience function to create a decompression output range.auto decompressOutputRange(OutputSink sink, CompressionFormat fmt)Convenience overload to create a decompression output range with just a format.DEFAULT_PROGRESS_INTERVAL = 64 * 1024Default progress callback interval in bytes (64 KiB).
Object gProvidersLockGuards every access to gProviders so registration and lookups are race-free.
TEST_IDENTITY_PROVIDER_VENDOR = "apiidentitycodec"TEST_IDENTITY_PROVIDER_NAME = "apiidentitycodec-lz4"