< Summary

Information
Class: System.IO.Compression.DeflateDecoder
Assembly: System.IO.Compression
File(s): D:\runner\runtime\src\libraries\System.IO.Compression\src\System\IO\Compression\DeflateDecoder.cs
Line coverage
0%
Covered lines: 0
Uncovered lines: 61
Coverable lines: 61
Total lines: 130
Line coverage: 0%
Branch coverage
0%
Covered branches: 0
Total branches: 22
Branch coverage: 0%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Cyclomatic complexity NPath complexity Sequence coverage
.ctor()100%110%
.ctor(...)100%110%
Dispose()0%220%
EnsureNotDisposed()100%110%
Decompress(...)0%16160%
TryDecompress(...)0%440%

File(s)

D:\runner\runtime\src\libraries\System.IO.Compression\src\System\IO\Compression\DeflateDecoder.cs

#LineLine coverage
 1// Licensed to the .NET Foundation under one or more agreements.
 2// The .NET Foundation licenses this file to you under the MIT license.
 3
 4using System.Buffers;
 5using System.Diagnostics;
 6using System.Runtime.InteropServices;
 7
 8namespace System.IO.Compression
 9{
 10    /// <summary>
 11    /// Provides methods and static methods to decode data compressed in the Deflate data format in a streamless, non-al
 12    /// </summary>
 13    public sealed class DeflateDecoder : IDisposable
 14    {
 15        private ZLibNative.ZLibStreamHandle? _state;
 16        private bool _disposed;
 17        private bool _finished;
 18
 19        /// <summary>
 20        /// Initializes a new instance of the <see cref="DeflateDecoder"/> class.
 21        /// </summary>
 22        /// <exception cref="IOException">Failed to create the <see cref="DeflateDecoder"/> instance.</exception>
 23        public DeflateDecoder()
 024            : this(ZLibNative.Deflate_DefaultWindowBits)
 025        {
 026        }
 27
 028        internal DeflateDecoder(int windowBits)
 029        {
 030            _state = ZLibNative.ZLibStreamHandle.CreateForInflate(windowBits);
 031        }
 32
 33        /// <summary>
 34        /// Frees and disposes unmanaged resources.
 35        /// </summary>
 36        public void Dispose()
 037        {
 038            _disposed = true;
 039            _state?.Dispose();
 040            _state = null;
 041        }
 42
 43        private void EnsureNotDisposed()
 044        {
 045            ObjectDisposedException.ThrowIf(_disposed, this);
 046        }
 47
 48        /// <summary>
 49        /// Decompresses a read-only byte span into a destination span.
 50        /// </summary>
 51        /// <param name="source">A read-only span of bytes containing the compressed source data.</param>
 52        /// <param name="destination">When this method returns, a byte span where the decompressed data is stored.</para
 53        /// <param name="bytesConsumed">When this method returns, the total number of bytes that were read from <paramre
 54        /// <param name="bytesWritten">When this method returns, the total number of bytes that were written to <paramre
 55        /// <returns>One of the enumeration values that describes the status with which the span-based operation finishe
 56        public OperationStatus Decompress(ReadOnlySpan<byte> source, Span<byte> destination, out int bytesConsumed, out 
 057        {
 058            EnsureNotDisposed();
 059            Debug.Assert(_state is not null);
 60
 061            bytesConsumed = 0;
 062            bytesWritten = 0;
 63
 064            if (_finished)
 065            {
 066                return OperationStatus.Done;
 67            }
 68
 069            if (destination.IsEmpty && source.Length > 0)
 070            {
 071                return OperationStatus.DestinationTooSmall;
 72            }
 73
 74            unsafe
 075            {
 076                fixed (byte* inputPtr = &MemoryMarshal.GetReference(source))
 077                fixed (byte* outputPtr = &MemoryMarshal.GetReference(destination))
 078                {
 079                    _state.NextIn = (IntPtr)inputPtr;
 080                    _state.AvailIn = (uint)source.Length;
 081                    _state.NextOut = (IntPtr)outputPtr;
 082                    _state.AvailOut = (uint)destination.Length;
 83
 084                    ZLibNative.ErrorCode errorCode = _state.Inflate(ZLibNative.FlushCode.NoFlush);
 85
 086                    bytesConsumed = source.Length - (int)_state.AvailIn;
 087                    bytesWritten = destination.Length - (int)_state.AvailOut;
 88
 089                    OperationStatus status = errorCode switch
 090                    {
 091                        ZLibNative.ErrorCode.Ok or ZLibNative.ErrorCode.BufError => _state.AvailOut == 0
 092                            ? OperationStatus.DestinationTooSmall
 093                            : OperationStatus.NeedMoreData,
 094                        ZLibNative.ErrorCode.StreamEnd => OperationStatus.Done,
 095                        _ => OperationStatus.InvalidData
 096                    };
 97
 98                    // Track if decompression is finished
 099                    if (errorCode == ZLibNative.ErrorCode.StreamEnd)
 0100                    {
 0101                        _finished = true;
 0102                    }
 103
 0104                    return status;
 105                }
 106            }
 0107        }
 108
 109        /// <summary>
 110        /// Tries to decompress a source byte span into a destination span.
 111        /// </summary>
 112        /// <param name="source">A read-only span of bytes containing the compressed source data.</param>
 113        /// <param name="destination">When this method returns, a span of bytes where the decompressed data is stored.</
 114        /// <param name="bytesWritten">When this method returns, the total number of bytes that were written to <paramre
 115        /// <returns><see langword="true"/> if the decompression operation was successful; <see langword="false"/> other
 116        public static bool TryDecompress(ReadOnlySpan<byte> source, Span<byte> destination, out int bytesWritten)
 0117        {
 0118            using var decoder = new DeflateDecoder();
 0119            OperationStatus status = decoder.Decompress(source, destination, out int consumed, out bytesWritten);
 120
 0121            bool success = status == OperationStatus.Done && consumed == source.Length;
 0122            if (!success)
 0123            {
 0124                bytesWritten = 0;
 0125            }
 126
 0127            return success;
 0128        }
 129    }
 130}