From c42dbdf94001e2447dc1becde977d47cad644ec2 Mon Sep 17 00:00:00 2001 From: vnugent Date: Mon, 23 Oct 2023 21:10:58 -0400 Subject: Native compressor api span support --- .../VNLib.Net.Compression/CompressionExtensions.cs | 52 +++++++++++++++++++++- .../VNLib.Net.Compression/INativeCompressor.cs | 14 ++++++ .../VNLib.Net.Compression/NativeCompressionLib.cs | 19 +++++++- 3 files changed, 83 insertions(+), 2 deletions(-) (limited to 'lib/Net.Compression/VNLib.Net.Compression') diff --git a/lib/Net.Compression/VNLib.Net.Compression/CompressionExtensions.cs b/lib/Net.Compression/VNLib.Net.Compression/CompressionExtensions.cs index ab451d9..4509b67 100644 --- a/lib/Net.Compression/VNLib.Net.Compression/CompressionExtensions.cs +++ b/lib/Net.Compression/VNLib.Net.Compression/CompressionExtensions.cs @@ -24,6 +24,7 @@ using System; using System.Buffers; +using System.Runtime.InteropServices; using VNLib.Net.Http; @@ -79,5 +80,54 @@ namespace VNLib.Net.Compression BytesWritten = (int)op->bytesWritten }; } + + /// + /// Compresses a block using the compressor context pointer provided + /// + /// + /// A pointer to the compressor context + /// A buffer to write the result to + /// The input block of memory to compress + /// A value that indicates if a flush is requested + /// The results of the compression operation + public static unsafe CompressionResult CompressBlock(this LibraryWrapper nativeLib, IntPtr comp, Span output, ReadOnlySpan input, bool finalBlock) + { + /* + * Since .NET only supports int32 size memory blocks + * we dont need to worry about integer overflow. + * + * Output sizes can never be larger than input + * sizes (read/written) + */ + + fixed(byte* inputPtr = &MemoryMarshal.GetReference(input), + outPtr = &MemoryMarshal.GetReference(output)) + { + //Create the operation struct + CompressionOperation operation; + CompressionOperation* op = &operation; + + op->flush = finalBlock ? 1 : 0; + op->bytesRead = 0; + op->bytesWritten = 0; + + //Configure the input and output buffers + op->inputBuffer = inputPtr; + op->inputSize = (uint)input.Length; + + op->outputBuffer = outPtr; + op->outputSize = (uint)output.Length; + + //Call the native compress function + nativeLib!.CompressBlock(comp, &operation); + + //Return the number of bytes written + return new() + { + BytesRead = (int)op->bytesRead, + BytesWritten = (int)op->bytesWritten + }; + } + } } -} \ No newline at end of file +} diff --git a/lib/Net.Compression/VNLib.Net.Compression/INativeCompressor.cs b/lib/Net.Compression/VNLib.Net.Compression/INativeCompressor.cs index c522860..ceaa87f 100644 --- a/lib/Net.Compression/VNLib.Net.Compression/INativeCompressor.cs +++ b/lib/Net.Compression/VNLib.Net.Compression/INativeCompressor.cs @@ -53,6 +53,13 @@ namespace VNLib.Net.Compression /// The number of bytes written to the output buffer int Flush(Memory buffer); + /// + /// Flushes all remaining data in the compressor to the output buffer + /// + /// The output buffer to write flushed compressor data to + /// The number of bytes written to the output buffer + int Flush(Span buffer); + /// /// Compresses the input block and writes the compressed data to the output block /// @@ -60,6 +67,13 @@ namespace VNLib.Net.Compression /// The output buffer to write compressed data to CompressionResult Compress(ReadOnlyMemory input, Memory output); + /// + /// Compresses the input block and writes the compressed data to the output block + /// + /// The input buffer to compress + /// The output buffer to write compressed data to + CompressionResult Compress(ReadOnlySpan input, Span output); + /// /// Gets the compressor block size if configured /// diff --git a/lib/Net.Compression/VNLib.Net.Compression/NativeCompressionLib.cs b/lib/Net.Compression/VNLib.Net.Compression/NativeCompressionLib.cs index 10bad84..438f777 100644 --- a/lib/Net.Compression/VNLib.Net.Compression/NativeCompressionLib.cs +++ b/lib/Net.Compression/VNLib.Net.Compression/NativeCompressionLib.cs @@ -98,6 +98,14 @@ namespace VNLib.Net.Compression return LibComp.CompressBlock(compressor, output, input, false); } + /// + public CompressionResult Compress(ReadOnlySpan input, Span output) + { + CompressorHandle.ThrowIfClosed(); + IntPtr compressor = CompressorHandle.DangerousGetHandle(); + return LibComp.CompressBlock(compressor, output, input, false); + } + /// public void Dispose() => CompressorHandle.Dispose(); @@ -106,7 +114,16 @@ namespace VNLib.Net.Compression { CompressorHandle.ThrowIfClosed(); IntPtr compressor = CompressorHandle.DangerousGetHandle(); - CompressionResult result = LibComp.CompressBlock(compressor, buffer, ReadOnlyMemory.Empty, true); + CompressionResult result = LibComp.CompressBlock(compressor, buffer, default, true); + return result.BytesWritten; + } + + /// + public int Flush(Span buffer) + { + CompressorHandle.ThrowIfClosed(); + IntPtr compressor = CompressorHandle.DangerousGetHandle(); + CompressionResult result = LibComp.CompressBlock(compressor, buffer, default, true); return result.BytesWritten; } -- cgit