diff options
author | vnugent <public@vaughnnugent.com> | 2023-10-23 21:10:58 -0400 |
---|---|---|
committer | vnugent <public@vaughnnugent.com> | 2023-10-23 21:10:58 -0400 |
commit | c42dbdf94001e2447dc1becde977d47cad644ec2 (patch) | |
tree | 5ffa252576604ca0b25c37b3b38a29c15d7f1abe /lib/Net.Compression/VNLib.Net.Compression | |
parent | aef1b25aae6fc27c4557dc7e4c9d75cbe22a1f8f (diff) |
Native compressor api span support
Diffstat (limited to 'lib/Net.Compression/VNLib.Net.Compression')
3 files changed, 83 insertions, 2 deletions
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 }; } + + /// <summary> + /// Compresses a block using the compressor context pointer provided + /// </summary> + /// <param name="nativeLib"></param> + /// <param name="comp">A pointer to the compressor context</param> + /// <param name="output">A buffer to write the result to</param> + /// <param name="input">The input block of memory to compress</param> + /// <param name="finalBlock">A value that indicates if a flush is requested</param> + /// <returns>The results of the compression operation</returns> + public static unsafe CompressionResult CompressBlock(this LibraryWrapper nativeLib, IntPtr comp, Span<byte> output, ReadOnlySpan<byte> 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 @@ -54,6 +54,13 @@ namespace VNLib.Net.Compression int Flush(Memory<byte> buffer); /// <summary> + /// Flushes all remaining data in the compressor to the output buffer + /// </summary> + /// <param name="buffer">The output buffer to write flushed compressor data to</param> + /// <returns>The number of bytes written to the output buffer</returns> + int Flush(Span<byte> buffer); + + /// <summary> /// Compresses the input block and writes the compressed data to the output block /// </summary> /// <param name="input">The input buffer to compress</param> @@ -61,6 +68,13 @@ namespace VNLib.Net.Compression CompressionResult Compress(ReadOnlyMemory<byte> input, Memory<byte> output); /// <summary> + /// Compresses the input block and writes the compressed data to the output block + /// </summary> + /// <param name="input">The input buffer to compress</param> + /// <param name="output">The output buffer to write compressed data to</param> + CompressionResult Compress(ReadOnlySpan<byte> input, Span<byte> output); + + /// <summary> /// Gets the compressor block size if configured /// </summary> /// <returns>The ideal input buffer size for compressing blocks, or <![CDATA[<1]]> if block size is unlimited</returns> 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 @@ -99,6 +99,14 @@ namespace VNLib.Net.Compression } ///<inheritdoc/> + public CompressionResult Compress(ReadOnlySpan<byte> input, Span<byte> output) + { + CompressorHandle.ThrowIfClosed(); + IntPtr compressor = CompressorHandle.DangerousGetHandle(); + return LibComp.CompressBlock(compressor, output, input, false); + } + + ///<inheritdoc/> public void Dispose() => CompressorHandle.Dispose(); ///<inheritdoc/> @@ -106,7 +114,16 @@ namespace VNLib.Net.Compression { CompressorHandle.ThrowIfClosed(); IntPtr compressor = CompressorHandle.DangerousGetHandle(); - CompressionResult result = LibComp.CompressBlock(compressor, buffer, ReadOnlyMemory<byte>.Empty, true); + CompressionResult result = LibComp.CompressBlock(compressor, buffer, default, true); + return result.BytesWritten; + } + + ///<inheritdoc/> + public int Flush(Span<byte> buffer) + { + CompressorHandle.ThrowIfClosed(); + IntPtr compressor = CompressorHandle.DangerousGetHandle(); + CompressionResult result = LibComp.CompressBlock(compressor, buffer, default, true); return result.BytesWritten; } |