From a342a9cc34348aec07ffff6026439da266e3524e Mon Sep 17 00:00:00 2001 From: "J. Zebedee" Date: Mon, 18 Sep 2023 16:11:20 -0500 Subject: [PATCH] Break out libdeflate_options from CustomMemoryAllocator --- src/LibDeflate/Imports/Compression.cs | 2 +- .../Imports/CustomMemoryAllocator.cs | 79 +----------------- src/LibDeflate/Imports/Decompression.cs | 2 +- src/LibDeflate/Imports/libdeflate_options.cs | 83 +++++++++++++++++++ .../CustomMemoryAllocatorTests.cs | 2 +- 5 files changed, 88 insertions(+), 80 deletions(-) create mode 100644 src/LibDeflate/Imports/libdeflate_options.cs diff --git a/src/LibDeflate/Imports/Compression.cs b/src/LibDeflate/Imports/Compression.cs index f178d98..de20e18 100644 --- a/src/LibDeflate/Imports/Compression.cs +++ b/src/LibDeflate/Imports/Compression.cs @@ -32,7 +32,7 @@ internal static class Compression /// Like but allows specifying advanced options per-compressor. /// [DllImport(Constants.DllName, CallingConvention = CallingConvention.Cdecl)] - public static extern libdeflate_compressor libdeflate_alloc_compressor_ex(int compression_level, in CustomMemoryAllocator.libdeflate_options options); + public static extern libdeflate_compressor libdeflate_alloc_compressor_ex(int compression_level, in libdeflate_options options); /// /// libdeflate_deflate_compress() performs raw DEFLATE compression on a buffer of diff --git a/src/LibDeflate/Imports/CustomMemoryAllocator.cs b/src/LibDeflate/Imports/CustomMemoryAllocator.cs index 904ec25..3bf1839 100644 --- a/src/LibDeflate/Imports/CustomMemoryAllocator.cs +++ b/src/LibDeflate/Imports/CustomMemoryAllocator.cs @@ -1,6 +1,6 @@ using System; -using System.Runtime.CompilerServices; using System.Runtime.InteropServices; + namespace LibDeflate.Imports; using size_t = UIntPtr; @@ -22,79 +22,4 @@ internal static class CustomMemoryAllocator /// [DllImport(Constants.DllName, CallingConvention = CallingConvention.Cdecl)] public static extern void libdeflate_set_memory_allocator(malloc_func malloc, free_func free); - - /// - /// Advanced options. This is the options structure that - /// - /// and - /// require. Most users won't need this and should just use the non-"_ex" - /// functions instead. - /// - internal readonly struct libdeflate_options - { - private static readonly size_t Size = (nuint)(nint)Unsafe.SizeOf(); - - public libdeflate_options(malloc_func malloc, free_func free) - { -#if NET6_0_OR_GREATER - ArgumentNullException.ThrowIfNull(malloc); - ArgumentNullException.ThrowIfNull(free); -#else - //TODO: add throwhelpers - if(malloc is null) - { - throw new ArgumentNullException(nameof(malloc)); - } - - if(free is null) - { - throw new ArgumentNullException(nameof(free)); - } -#endif - - this.malloc = malloc; - this.free = free; - } - - /// - /// This field must be set to the struct size. This field exists for - /// extensibility, so that fields can be appended to this struct in - /// future versions of libdeflate while still supporting old binaries. - /// - public readonly size_t sizeof_options = Size; - /// - /// An optional custom memory allocator to use for this (de)compressor. - /// 'malloc_func' must be a function that behaves like malloc(). - /// - /// - /// This is useful in cases where a process might have multiple users of - /// libdeflate who want to use different memory allocators. For example, - /// a library might want to use libdeflate with a custom memory allocator - /// without interfering with user code that might use libdeflate too. - /// - /// This takes priority over the "global" memory allocator (which by - /// default is malloc() and free(), but can be changed by - /// libdeflate_set_memory_allocator()). Moreover, libdeflate will never - /// call the "global" memory allocator if a per-(de)compressor custom - /// allocator is always given. - /// - public readonly malloc_func malloc; - /// - /// An optional custom memory deallocator to use for this (de)compressor. - /// 'free_func' must be a function that behaves like free(). - /// - /// - /// This is useful in cases where a process might have multiple users of - /// libdeflate who want to use different memory allocators. For example, - /// a library might want to use libdeflate with a custom memory allocator - /// without interfering with user code that might use libdeflate too. - /// - /// This takes priority over the "global" memory allocator (which by - /// default is malloc() and free(), but can be changed by - /// libdeflate_set_memory_allocator()). Moreover, libdeflate will never - /// call the "global" memory allocator if a per-(de)compressor custom - /// allocator is always given. - /// - public readonly free_func free; - } -} +} \ No newline at end of file diff --git a/src/LibDeflate/Imports/Decompression.cs b/src/LibDeflate/Imports/Decompression.cs index 45bd969..8c343f2 100644 --- a/src/LibDeflate/Imports/Decompression.cs +++ b/src/LibDeflate/Imports/Decompression.cs @@ -55,7 +55,7 @@ public enum libdeflate_result /// Like but allows specifying advanced options per-decompressor. /// [DllImport(Constants.DllName, CallingConvention = CallingConvention.Cdecl)] - public static extern libdeflate_decompressor libdeflate_alloc_decompressor_ex(in CustomMemoryAllocator.libdeflate_options options); + public static extern libdeflate_decompressor libdeflate_alloc_decompressor_ex(in libdeflate_options options); /// /// libdeflate_deflate_decompress() decompresses the DEFLATE-compressed stream diff --git a/src/LibDeflate/Imports/libdeflate_options.cs b/src/LibDeflate/Imports/libdeflate_options.cs new file mode 100644 index 0000000..4fd7a43 --- /dev/null +++ b/src/LibDeflate/Imports/libdeflate_options.cs @@ -0,0 +1,83 @@ +using System; +using System.Runtime.CompilerServices; +namespace LibDeflate.Imports; + +using static LibDeflate.Imports.CustomMemoryAllocator; +using size_t = UIntPtr; + +/// +/// Advanced options. This is the options structure that +/// +/// and +/// require. Most users won't need this and should just use the non-"_ex" +/// functions instead. +/// +internal readonly struct libdeflate_options +{ + private static readonly size_t Size = (nuint)(nint)Unsafe.SizeOf(); + + public libdeflate_options(malloc_func malloc, free_func free) + { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(malloc); + ArgumentNullException.ThrowIfNull(free); +#else + //TODO: add throwhelpers + if (malloc is null) + { + throw new ArgumentNullException(nameof(malloc)); + } + + if (free is null) + { + throw new ArgumentNullException(nameof(free)); + } +#endif + this.sizeof_options = Size; + this.malloc = malloc; + this.free = free; + } + + /// + /// This field must be set to the struct size. This field exists for + /// extensibility, so that fields can be appended to this struct in + /// future versions of libdeflate while still supporting old binaries. + /// + public readonly size_t sizeof_options; + + /// + /// An optional custom memory allocator to use for this (de)compressor. + /// 'malloc_func' must be a function that behaves like malloc(). + /// + /// + /// This is useful in cases where a process might have multiple users of + /// libdeflate who want to use different memory allocators. For example, + /// a library might want to use libdeflate with a custom memory allocator + /// without interfering with user code that might use libdeflate too. + /// + /// This takes priority over the "global" memory allocator (which by + /// default is malloc() and free(), but can be changed by + /// libdeflate_set_memory_allocator()). Moreover, libdeflate will never + /// call the "global" memory allocator if a per-(de)compressor custom + /// allocator is always given. + /// + public readonly malloc_func malloc; + + /// + /// An optional custom memory deallocator to use for this (de)compressor. + /// 'free_func' must be a function that behaves like free(). + /// + /// + /// This is useful in cases where a process might have multiple users of + /// libdeflate who want to use different memory allocators. For example, + /// a library might want to use libdeflate with a custom memory allocator + /// without interfering with user code that might use libdeflate too. + /// + /// This takes priority over the "global" memory allocator (which by + /// default is malloc() and free(), but can be changed by + /// libdeflate_set_memory_allocator()). Moreover, libdeflate will never + /// call the "global" memory allocator if a per-(de)compressor custom + /// allocator is always given. + /// + public readonly free_func free; +} diff --git a/test/LibDeflate.DangerousTests/CustomMemoryAllocatorTests.cs b/test/LibDeflate.DangerousTests/CustomMemoryAllocatorTests.cs index 507dd10..2f2f2d8 100644 --- a/test/LibDeflate.DangerousTests/CustomMemoryAllocatorTests.cs +++ b/test/LibDeflate.DangerousTests/CustomMemoryAllocatorTests.cs @@ -57,7 +57,7 @@ public void UsePerCompressorCustomAllocatorsTest() int localMallocs = 0; int localFrees = 0; - var options = new CustomMemoryAllocator.libdeflate_options((nuint len) => + var options = new libdeflate_options((nuint len) => { localMallocs++; return Marshal.AllocHGlobal((nint)len);