< Summary

Information
Class: Microsoft.Win32.SafeHandles.SafeZstdDecompressHandle
Assembly: System.IO.Compression
File(s): D:\runner\runtime\src\libraries\Common\src\Microsoft\Win32\SafeHandles\SafeZstdHandle.cs
Line coverage
0%
Covered lines: 0
Uncovered lines: 51
Coverable lines: 51
Total lines: 201
Line coverage: 0%
Branch coverage
0%
Covered branches: 0
Total branches: 12
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%
ReleaseHandle()0%440%
SetDictionary(...)100%110%
SetPrefix(...)0%440%
Reset()0%440%

File(s)

D:\runner\runtime\src\libraries\Common\src\Microsoft\Win32\SafeHandles\SafeZstdHandle.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;
 5using System.Buffers;
 6using System.Diagnostics;
 7using System.Runtime.InteropServices;
 8using System.IO.Compression;
 9
 10namespace Microsoft.Win32.SafeHandles
 11{
 12    internal sealed class SafeZstdCompressHandle : SafeHandle
 13    {
 14        internal SafeZstdCDictHandle? _dictionary;
 15        internal MemoryHandle? _prefixHandle;
 16        public SafeZstdCompressHandle() : base(IntPtr.Zero, true) { }
 17
 18        protected override bool ReleaseHandle()
 19        {
 20            Interop.Zstd.ZSTD_freeCCtx(handle);
 21
 22            // release the addref we took in SetDictionary
 23            _dictionary?.DangerousRelease();
 24
 25            if (_prefixHandle != null)
 26            {
 27                _prefixHandle.Value.Dispose();
 28                _prefixHandle = null;
 29            }
 30            return true;
 31        }
 32
 33        public void SetDictionary(SafeZstdCDictHandle dictionary)
 34        {
 35            Debug.Assert(_dictionary == null);
 36            Debug.Assert(dictionary != null);
 37
 38            bool added = false;
 39            try
 40            {
 41                dictionary.DangerousAddRef(ref added);
 42                ZstandardUtils.ThrowIfError(Interop.Zstd.ZSTD_CCtx_refCDict(this, dictionary));
 43
 44                _dictionary = dictionary;
 45            }
 46            catch when (added)
 47            {
 48                dictionary.DangerousRelease();
 49                throw;
 50            }
 51        }
 52
 53        public unsafe nuint SetPrefix(ReadOnlyMemory<byte> prefix)
 54        {
 55            MemoryHandle handle = prefix.Pin();
 56
 57            nuint result = Interop.Zstd.ZSTD_CCtx_refPrefix(this, (byte*)handle.Pointer, (nuint)prefix.Length);
 58
 59            if (Interop.Zstd.ZSTD_isError(result) != 0)
 60            {
 61                handle.Dispose();
 62            }
 63            else
 64            {
 65                _prefixHandle?.Dispose();
 66                _prefixHandle = handle;
 67            }
 68
 69            return result;
 70        }
 71
 72        public unsafe void Reset()
 73        {
 74            ZstandardUtils.ThrowIfError(Interop.Zstd.ZSTD_CCtx_reset(this, Interop.Zstd.ZstdResetDirective.ZSTD_reset_se
 75
 76            // Restore the dictionary or clear the prefix before releasing its pinned memory.
 77            if (_prefixHandle != null)
 78            {
 79                nuint result = _dictionary is not null
 80                    ? Interop.Zstd.ZSTD_CCtx_refCDict(this, _dictionary)
 81                    : Interop.Zstd.ZSTD_CCtx_refPrefix(this, null, 0);
 82                ZstandardUtils.ThrowIfError(result);
 83                _prefixHandle.Value.Dispose();
 84                _prefixHandle = null;
 85            }
 86        }
 87
 88        public override bool IsInvalid => handle == IntPtr.Zero;
 89    }
 90
 91    internal sealed class SafeZstdDecompressHandle : SafeHandle
 92    {
 93        internal SafeZstdDDictHandle? _dictionary;
 94        internal MemoryHandle? _prefixHandle;
 095        public SafeZstdDecompressHandle() : base(IntPtr.Zero, true) { }
 96
 97        protected override bool ReleaseHandle()
 098        {
 099            Interop.Zstd.ZSTD_freeDCtx(handle);
 100
 101            // release the addref we took in SetDictionary
 0102            _dictionary?.DangerousRelease();
 103
 0104            if (_prefixHandle != null)
 0105            {
 0106                _prefixHandle.Value.Dispose();
 0107                _prefixHandle = null;
 0108            }
 0109            return true;
 0110        }
 111
 112        public void SetDictionary(SafeZstdDDictHandle dictionary)
 0113        {
 0114            Debug.Assert(_dictionary == null);
 0115            Debug.Assert(dictionary != null);
 116
 0117            bool added = false;
 118            try
 0119            {
 0120                dictionary.DangerousAddRef(ref added);
 0121                ZstandardUtils.ThrowIfError(Interop.Zstd.ZSTD_DCtx_refDDict(this, dictionary));
 122
 0123                _dictionary = dictionary;
 0124            }
 0125            catch when (added)
 0126            {
 0127                dictionary.DangerousRelease();
 0128                throw;
 129            }
 0130        }
 131
 132        public unsafe nuint SetPrefix(ReadOnlyMemory<byte> prefix)
 0133        {
 0134            MemoryHandle handle = prefix.Pin();
 135
 0136            nuint result = Interop.Zstd.ZSTD_DCtx_refPrefix(this, (byte*)handle.Pointer, (nuint)prefix.Length);
 137
 0138            if (Interop.Zstd.ZSTD_isError(result) != 0)
 0139            {
 0140                handle.Dispose();
 0141            }
 142            else
 0143            {
 0144                _prefixHandle?.Dispose();
 0145                _prefixHandle = handle;
 0146            }
 147
 0148            return result;
 0149        }
 150
 151        public unsafe void Reset()
 0152        {
 0153            ZstandardUtils.ThrowIfError(Interop.Zstd.ZSTD_DCtx_reset(this, Interop.Zstd.ZstdResetDirective.ZSTD_reset_se
 154
 155            // Restore the dictionary or clear the prefix before releasing its pinned memory.
 0156            if (_prefixHandle != null)
 0157            {
 0158                nuint result = _dictionary is not null
 0159                    ? Interop.Zstd.ZSTD_DCtx_refDDict(this, _dictionary)
 0160                    : Interop.Zstd.ZSTD_DCtx_refPrefix(this, null, 0);
 0161                ZstandardUtils.ThrowIfError(result);
 0162                _prefixHandle.Value.Dispose();
 0163                _prefixHandle = null;
 0164            }
 0165        }
 166
 0167        public override bool IsInvalid => handle == IntPtr.Zero;
 168    }
 169
 170    internal sealed class SafeZstdCDictHandle : SafeHandle
 171    {
 172        public SafeZstdCDictHandle() : base(IntPtr.Zero, true) { }
 173
 174        internal PinnedGCHandle<byte[]> _pinnedData;
 175
 176        protected override bool ReleaseHandle()
 177        {
 178            Interop.Zstd.ZSTD_freeCDict(handle);
 179            _pinnedData.Dispose();
 180            return true;
 181        }
 182
 183        public override bool IsInvalid => handle == IntPtr.Zero;
 184    }
 185
 186    internal sealed class SafeZstdDDictHandle : SafeHandle
 187    {
 188        public SafeZstdDDictHandle() : base(IntPtr.Zero, true) { }
 189
 190        internal PinnedGCHandle<byte[]> _pinnedData;
 191
 192        protected override bool ReleaseHandle()
 193        {
 194            Interop.Zstd.ZSTD_freeDDict(handle);
 195            _pinnedData.Dispose();
 196            return true;
 197        }
 198
 199        public override bool IsInvalid => handle == IntPtr.Zero;
 200    }
 201}