private static void ThrowIfError(ulong code) { if (Zstandard64NativeMethods.ZSTD_isError(code)) { var errorPtr = Zstandard64NativeMethods.ZSTD_getErrorName(code); var errorMsg = Marshal.PtrToStringAnsi(errorPtr); throw new IOException(errorMsg); } }
public void Dispose() { switch (_compressionMode) { case CompressionMode.Compress: Zstandard64NativeMethods.ZSTD_freeCStream(_zstreamPointer); break; case CompressionMode.Decompress: Zstandard64NativeMethods.ZSTD_freeDStream(_zstreamPointer); break; } }
private void InitializeIfNotAlreadyInitialized() { if (!_operationInitialized) { _operationInitialized = true; switch (_compressionMode) { case CompressionMode.Compress: Zstandard64NativeMethods.ZSTD_initCStream(_zstreamPointer, _compressionLevel); // start a new compression operation break; case CompressionMode.Decompress: Zstandard64NativeMethods.ZSTD_initDStream(_zstreamPointer); // start a new decompression operation break; } } }
public void Decompress( OperationContext operationContext, int compressedOffset, int inputCompressedSize, int inputUncompressedSize, out int compressedBytesProcessed, out int uncompressedBytesProcessed) { Ensure.IsNotNull(operationContext, nameof(operationContext)); Ensure.That(_compressionMode == CompressionMode.Decompress, nameof(_compressionMode)); Ensure.IsGreaterThanOrEqualToZero(inputCompressedSize, nameof(inputCompressedSize)); Ensure.IsGreaterThanOrEqualToZero(inputUncompressedSize, nameof(inputUncompressedSize)); InitializeIfNotAlreadyInitialized(); // apply reading progress on CompressedPinnedBufferWalker operationContext.CompressedPinnedBufferWalker.Offset = compressedOffset; // compressed data var inputNativeBuffer = CreateNativeBuffer( inputCompressedSize <= 0 ? null : operationContext.CompressedPinnedBufferWalker, inputCompressedSize <= 0 ? 0 : (ulong)inputCompressedSize); // uncompressed data var outputNativeBuffer = CreateNativeBuffer( operationContext.UncompressedPinnedBufferWalker, // operation result (ulong)inputUncompressedSize); // decompress inputNativeBuffer to outputNativeBuffer _ = Zstandard64NativeMethods.ZSTD_decompressStream( _zstreamPointer, outputNativeBuffer, inputNativeBuffer); uncompressedBytesProcessed = (int)outputNativeBuffer.Position; // because start Position is always 0 compressedBytesProcessed = (int)inputNativeBuffer.Position; // because start Position is always 0 operationContext.UncompressedPinnedBufferWalker.Offset += uncompressedBytesProcessed; // CompressedPinnedBufferWalker.Offset will be calculated on stream side }
public ZstandardNativeWrapper(CompressionMode compressionMode, int compressionLevel) { _compressionLevel = compressionLevel; _compressionMode = compressionMode; switch (_compressionMode) { case CompressionMode.Compress: // calculate recommended size for input buffer _recommendedZstreamInputSize = Zstandard64NativeMethods.ZSTD_CStreamInSize(); // calculate recommended size for output buffer. Guarantee to successfully flush at least one complete compressed block _recommendedZstreamOutputSize = Zstandard64NativeMethods.ZSTD_CStreamOutSize(); _zstreamPointer = Zstandard64NativeMethods.ZSTD_createCStream(); // create resource break; case CompressionMode.Decompress: // calculate recommended size for input buffer _recommendedZstreamInputSize = Zstandard64NativeMethods.ZSTD_DStreamInSize(); // calculate recommended size for output buffer. Guarantee to successfully flush at least one complete block in all circumstances _recommendedZstreamOutputSize = Zstandard64NativeMethods.ZSTD_DStreamOutSize(); _zstreamPointer = Zstandard64NativeMethods.ZSTD_createDStream(); // create resource break; } }
public IEnumerable <int> StepwiseFlush(BufferInfo compressedBufferInfo) { if (_compressionMode != CompressionMode.Compress) { throw new InvalidDataException($"{nameof(StepwiseFlush)} must be called only from Compress mode."); } using (var operationContext = InitializeOperationContext(compressedBufferInfo)) { yield return(ProcessCompressedOutput(operationContext, (zcs, buffer) => Zstandard64NativeMethods.ZSTD_flushStream(zcs, buffer))); } using (var operationContext = InitializeOperationContext(compressedBufferInfo)) { yield return(ProcessCompressedOutput(operationContext, (zcs, buffer) => Zstandard64NativeMethods.ZSTD_endStream(zcs, buffer))); } int ProcessCompressedOutput(OperationContext context, Action <IntPtr, NativeBufferInfo> outputAction) { var outputNativeBuffer = CreateNativeBuffer( context.CompressedPinnedBufferWalker, _recommendedZstreamOutputSize); outputAction(_zstreamPointer, outputNativeBuffer); return((int)outputNativeBuffer.Position); } }