< Summary

Information
Class: System.IO.Compression.ZstandardUtils
Assembly: System.IO.Compression
File(s): D:\runner\runtime\src\libraries\System.IO.Compression\src\System\IO\Compression\Zstandard\ZstandardUtils.cs
Line coverage
0%
Covered lines: 0
Uncovered lines: 45
Coverable lines: 45
Total lines: 99
Line coverage: 0%
Branch coverage
0%
Covered branches: 0
Total branches: 23
Branch coverage: 0%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Cyclomatic complexity NPath complexity Sequence coverage
.cctor()100%110%
IsError(...)100%110%
IsError(...)0%220%
GetErrorMessage(...)0%220%
ThrowIfError(...)0%220%
Throw(...)100%110%
CreateExceptionForError(...)0%10100%
GetQualityFromCompressionLevel(...)0%550%

File(s)

D:\runner\runtime\src\libraries\System.IO.Compression\src\System\IO\Compression\Zstandard\ZstandardUtils.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.Diagnostics;
 5using System.Diagnostics.CodeAnalysis;
 6
 7namespace System.IO.Compression
 8{
 9    internal static class ZstandardUtils
 10    {
 11        // Zstandard compression level constants from native library
 012        internal static readonly int Quality_Min = Interop.Zstd.ZSTD_minCLevel();
 013        internal static readonly int Quality_Max = Interop.Zstd.ZSTD_maxCLevel();
 014        internal static readonly int Quality_Default = Interop.Zstd.ZSTD_defaultCLevel();
 15
 16        // Window size constraints based on Zstandard specification
 17        internal const int WindowLog_Min = 10;    // 1KB window
 018        internal static int WindowLog_Max => Environment.Is64BitProcess ? 31 : 30;    // 1GB or 2GB window, depending on
 19        internal const int WindowLog_Default = 23; // 8MB window
 20
 21        internal const int TargetBlockSize_Min = 1340;
 22        internal const int TargetBlockSize_Max = 131072;   // (2^17)
 23
 24        // Buffer sizes for Zstandard operations
 25        internal const int DefaultInternalBufferSize = (1 << 16) - 16; // 65520 bytes, similar to Brotli
 26
 27        /// <summary>Checks if a Zstandard operation result indicates an error.</summary>
 028        internal static bool IsError(nuint result) => Interop.Zstd.ZSTD_isError(result) != 0;
 29        internal static bool IsError(nuint result, out Interop.Zstd.ZSTD_error error)
 030        {
 031            if (IsError(result))
 032            {
 033                error = (Interop.Zstd.ZSTD_error)result;
 034                return true;
 35            }
 36
 037            error = Interop.Zstd.ZSTD_error.no_error;
 038            return false;
 039        }
 40
 41        /// <summary>Gets the error message for a Zstandard error code.</summary>
 42        internal static string GetErrorMessage(Interop.Zstd.ZSTD_error error)
 043        {
 044            IntPtr errorNamePtr = Interop.Zstd.ZSTD_getErrorName((nuint)error);
 045            return System.Runtime.InteropServices.Marshal.PtrToStringAnsi(errorNamePtr) ?? $"Unknown error {error}";
 046        }
 47
 48        internal static void ThrowIfError(nuint result)
 049        {
 050            if (IsError(result, out var error))
 051            {
 052                Throw(error);
 53            }
 054        }
 55
 56        [DoesNotReturn]
 57        internal static void Throw(Interop.Zstd.ZSTD_error error)
 058        {
 059            Debug.Assert(IsError((nuint)error));
 060            throw CreateExceptionForError(error);
 61        }
 62
 63        internal static Exception CreateExceptionForError(Interop.Zstd.ZSTD_error error)
 064        {
 065            Debug.Assert(IsError((nuint)error));
 66
 067            switch (error)
 68            {
 69                case Interop.Zstd.ZSTD_error.frameParameter_windowTooLarge:
 070                    return new IOException(SR.ZstandardDecoder_WindowTooLarge);
 71
 72                case Interop.Zstd.ZSTD_error.dictionary_wrong:
 073                    return new InvalidDataException(SR.ZstandardDecoder_DictionaryWrong);
 74
 75                case Interop.Zstd.ZSTD_error.memory_allocation:
 076                    return new OutOfMemoryException();
 77
 78                case Interop.Zstd.ZSTD_error.stage_wrong:
 079                    return new InvalidOperationException(SR.ZstandardEncoderDecoder_InvalidState);
 80
 81                default:
 082                    return new IOException(SR.Format(SR.Zstd_InternalError, GetErrorMessage(error)));
 83            }
 084        }
 85
 86        internal static int GetQualityFromCompressionLevel(CompressionLevel compressionLevel) =>
 087            compressionLevel switch
 088            {
 089                // zstd supports negative quality levels, all negative levels map to the
 090                // same behavior (essentially no compression). Quality 0 means "default" = 3.
 091                // 1 is therefore the fastest compression level with some compression.
 092                CompressionLevel.NoCompression => Quality_Min,
 093                CompressionLevel.Fastest => 1,
 094                CompressionLevel.Optimal => Quality_Default,
 095                CompressionLevel.SmallestSize => Quality_Max,
 096                _ => throw new ArgumentOutOfRangeException(nameof(compressionLevel), compressionLevel, SR.ArgumentOutOfR
 097            };
 98    }
 99}