< Summary

Line coverage
0%
Covered lines: 0
Uncovered lines: 46
Coverable lines: 46
Total lines: 107
Line coverage: 0%
Branch coverage
0%
Covered branches: 0
Total branches: 25
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)

https://raw.githubusercontent.com/dotnet/runtime/811a7eabb75c42db53440e8ba3f60c07511cfd1f/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        // Hash table and chain table constraints based on Zstandard specification
 22        internal const int HashLog_Min = 6;
 23        internal const int HashLog_Max = 30;
 24
 25        internal const int ChainLog_Min = 6;
 026        internal static int ChainLog_Max => Environment.Is64BitProcess ? 30 : 29;
 27
 28        internal const int TargetBlockSize_Min = 1340;
 29        internal const int TargetBlockSize_Max = 131072;   // (2^17)
 30
 31        // Buffer sizes for Zstandard operations
 32        internal const int DefaultInternalBufferSize = (1 << 16) - 16; // 65520 bytes, similar to Brotli
 33
 34        /// <summary>Checks if a Zstandard operation result indicates an error.</summary>
 035        internal static bool IsError(nuint result) => Interop.Zstd.ZSTD_isError(result) != 0;
 36        internal static bool IsError(nuint result, out Interop.Zstd.ZSTD_error error)
 037        {
 038            if (IsError(result))
 039            {
 040                error = (Interop.Zstd.ZSTD_error)result;
 041                return true;
 42            }
 43
 044            error = Interop.Zstd.ZSTD_error.no_error;
 045            return false;
 046        }
 47
 48        /// <summary>Gets the error message for a Zstandard error code.</summary>
 49        internal static string GetErrorMessage(Interop.Zstd.ZSTD_error error)
 050        {
 051            IntPtr errorNamePtr = Interop.Zstd.ZSTD_getErrorName((nuint)error);
 052            return System.Runtime.InteropServices.Marshal.PtrToStringAnsi(errorNamePtr) ?? $"Unknown error {error}";
 053        }
 54
 55        internal static void ThrowIfError(nuint result)
 056        {
 057            if (IsError(result, out var error))
 058            {
 059                Throw(error);
 60            }
 061        }
 62
 63        [DoesNotReturn]
 64        internal static void Throw(Interop.Zstd.ZSTD_error error)
 065        {
 066            Debug.Assert(IsError((nuint)error));
 067            throw CreateExceptionForError(error);
 68        }
 69
 70        internal static Exception CreateExceptionForError(Interop.Zstd.ZSTD_error error)
 071        {
 072            Debug.Assert(IsError((nuint)error));
 73
 074            switch (error)
 75            {
 76                case Interop.Zstd.ZSTD_error.frameParameter_windowTooLarge:
 077                    return new IOException(SR.ZstandardDecoder_WindowTooLarge);
 78
 79                case Interop.Zstd.ZSTD_error.dictionary_wrong:
 080                    return new InvalidDataException(SR.ZstandardDecoder_DictionaryWrong);
 81
 82                case Interop.Zstd.ZSTD_error.memory_allocation:
 083                    return new OutOfMemoryException();
 84
 85                case Interop.Zstd.ZSTD_error.stage_wrong:
 086                    return new InvalidOperationException(SR.ZstandardEncoderDecoder_InvalidState);
 87
 88                default:
 089                    return new IOException(SR.Format(SR.Zstd_InternalError, GetErrorMessage(error)));
 90            }
 091        }
 92
 93        internal static int GetQualityFromCompressionLevel(CompressionLevel compressionLevel) =>
 094            compressionLevel switch
 095            {
 096                // zstd supports negative quality levels, all negative levels map to the
 097                // same behavior (essentially no compression). Quality 0 means "default" = 3.
 098                // 1 is therefore the fastest compression level with some compression.
 099                CompressionLevel.NoCompression => Quality_Min,
 0100                CompressionLevel.Fastest => 1,
 0101                CompressionLevel.Optimal => Quality_Default,
 0102                CompressionLevel.SmallestSize => Quality_Max,
 0103                _ => throw new ArgumentOutOfRangeException(nameof(compressionLevel), compressionLevel, SR.ArgumentOutOfR
 0104            };
 105    }
 106}
 107