Beispiel #1
0
        /// <summary>
        /// Gets the value range for <paramref name="parameter"/>
        /// </summary>
        public static Range GetParameterBounds(ZstdCompressionParameter parameter)
        {
            ZstdBounds bounds = Native.ZSTD_cParam_getBounds(parameter);

            Zstd.ThrowOnError(bounds.ErrorCode);
            return(bounds.GetRange());
        }
Beispiel #2
0
        /// <summary>
        /// Gets the value of a parameter
        /// </summary>
        public int GetParameter(ZstdCompressionParameter parameter)
        {
            int value = 0;

            unsafe
            {
                Zstd.ThrowOnError(Native.ZSTD_CCtx_getParameter(this._context, parameter, (IntPtr)(&value)));
            }

            return(value);
        }
Beispiel #3
0
        /// <summary>
        /// Compresses data in <paramref name="buffer"/> starting at <paramref name="offset"/> with <paramref name="size"/>
        /// using the specified <paramref name="compressionLevel"/> and parameters set on this <see cref="ZstdCompressionContext"/>
        /// </summary>
        /// <param name="buffer">The buffer to compress</param>
        /// <param name="offset">The offset at which the data to compress starts</param>
        /// <param name="size">The size of the data to compress</param>
        /// <param name="compressionLevel">The compression level to use</param>
        /// <returns>The compressed buffer</returns>
        /// <remarks>
        /// This method will usually cause a double heap allocation of the compressed buffer,
        /// it is recommended to use <see cref="Compress(ReadOnlyMemory{byte}, int, int, int)"/> if you want to avoid this
        /// </remarks>
        public byte[] Compress(byte[] buffer, int offset, int size, int compressionLevel = Native.ZSTD_CLEVEL_DEFAULT)
        {
            if (buffer == null)
            {
                throw new ArgumentNullException(nameof(buffer), $"{nameof(buffer)} cannot be null");
            }

            Zstd.ValidateCompressionArguments(buffer.Length, offset, size, compressionLevel);

            // Allocate compressed buffer
            Size compressionBound = Native.ZSTD_compressBound(new Size((uint)size));

            byte[] compressedBuffer = new byte[compressionBound.ToUInt32()];

            Size compressedBufferSize = Size.Zero;

            unsafe
            {
                fixed(byte *compressedBufferPointer = compressedBuffer)
                fixed(byte *uncompressedBufferPointer = buffer)
                {
                    if (this.Dictionary == null)
                    {
                        compressedBufferSize = Native.ZSTD_compress2(
                            this._context,
                            (IntPtr)compressedBufferPointer, compressionBound,
                            (IntPtr)(uncompressedBufferPointer + offset), (Size)size);
                    }
                    else
                    {
                        compressedBufferSize = Native.ZSTD_compress_usingCDict(
                            this._context,
                            (IntPtr)compressedBufferPointer, compressionBound,
                            (IntPtr)(uncompressedBufferPointer + offset), (Size)size,
                            this.Dictionary.GetCompressionDictionary(compressionLevel));
                    }
                }
            }

            // Check for errors
            Zstd.ThrowOnError(compressedBufferSize);

            // If compressionBound is same as the amount of compressed bytes then we can return the same array
            // otherwise we need to allocate a new one :/
            if (compressionBound != compressedBufferSize)
            {
                Array.Resize(ref compressedBuffer, (int)compressedBufferSize);
            }

            return(compressedBuffer);
        }
Beispiel #4
0
        /// <summary>
        /// Compresses data in <paramref name="memory"/> starting at <paramref name="offset"/> with <paramref name="size"/>
        /// using the specified <paramref name="compressionLevel"/> and parameters set on this <see cref="ZstdCompressionContext"/>
        /// </summary>
        /// <param name="memory">The buffer to compress</param>
        /// <param name="offset">The offset at which the data to compress starts</param>
        /// <param name="size">The size of the data to compress</param>
        /// <param name="compressionLevel">The compression level to use</param>
        /// <returns>The compressed buffer wrapped in <see cref="Memory{Byte}"/></returns>
        public Memory <byte> Compress(ReadOnlyMemory <byte> memory, int offset, int size, int compressionLevel = Native.ZSTD_CLEVEL_DEFAULT)
        {
            Zstd.ValidateCompressionArguments(memory.Length, offset, size, compressionLevel);

            // Allocate compressed buffer
            Size compressionBound = Native.ZSTD_compressBound(new Size((uint)size));

            byte[] compressedBuffer = new byte[compressionBound.ToUInt32()];

            // Get handles to buffers
            using MemoryHandle compressedBufferHandle   = compressedBuffer.AsMemory().Pin();
            using MemoryHandle uncompressedBufferHandle = memory.Pin();

            unsafe
            {
                // Get raw pointers from handles
                IntPtr compressedBufferPointer   = new IntPtr(compressedBufferHandle.Pointer);
                IntPtr uncompressedBufferPointer = new IntPtr(uncompressedBufferHandle.Pointer);

                Size compressedBufferSize;
                if (this.Dictionary == null)
                {
                    compressedBufferSize = Native.ZSTD_compressCCtx(
                        this._context,
                        compressedBufferPointer, compressionBound,
                        uncompressedBufferPointer + offset, (Size)size,
                        compressionLevel);
                }
                else
                {
                    compressedBufferSize = Native.ZSTD_compress_usingCDict(
                        this._context,
                        compressedBufferPointer, compressionBound,
                        uncompressedBufferPointer + offset, (Size)size,
                        this.Dictionary.GetCompressionDictionary(compressionLevel));
                }


                // Check for errors
                Zstd.ThrowOnError(compressedBufferSize);

                return(compressedBuffer.AsMemory(0, (int)compressedBufferSize.ToUInt32()));
            }
        }
        /// <summary>
        /// Decompresses data with <paramref name="size"/> at <paramref name="offset"/> in <paramref name="buffer"/> using this <see cref="ZstdDecompressionContext"/>
        /// </summary>
        /// <param name="buffer">The compressed data buffer</param>
        /// <param name="offset">The offset of the compressed data</param>
        /// <param name="size">The size of the compressed data</param>
        /// <param name="uncompressedSize">Uncompressed size of <paramref name="buffer"/></param>
        /// <returns>The uncompressed buffer</returns>
        /// <remarks>If you do not know the uncompressed size then it is recommended to use <see cref="ZstdStream"/></remarks>
        public byte[] Decompress(byte[] buffer, int offset, int size, int uncompressedSize)
        {
            Zstd.ValidateDecompressionArguments(buffer.Length, offset, size, uncompressedSize);

            // Allocate uncompressed buffer
            byte[] uncompressedBuffer = new byte[uncompressedSize];

            Size uncompressedBufferSize = Size.Zero;

            unsafe
            {
                fixed(byte *uncompressedBufferPtr = uncompressedBuffer)
                fixed(byte *compressedBufferPtr = buffer)
                {
                    if (this.Dictionary == null)
                    {
                        uncompressedBufferSize = Native.ZSTD_decompressDCtx(
                            this._context,
                            (IntPtr)uncompressedBufferPtr, (Size)uncompressedSize,
                            (IntPtr)(compressedBufferPtr + offset), (Size)size);
                    }
                    else
                    {
                        uncompressedBufferSize = Native.ZSTD_decompress_usingDDict(
                            this._context,
                            (IntPtr)uncompressedBufferPtr, (Size)uncompressedSize,
                            (IntPtr)(compressedBufferPtr + offset), (Size)size,
                            this.Dictionary.GetDecompressionDictionary());
                    }
                }
            }

            // Check for errors
            Zstd.ThrowOnError(uncompressedBufferSize);

            // Check for possiblity that user passed in higher than required uncompressed size
            if (uncompressedSize != uncompressedBufferSize.ToUInt32())
            {
                Array.Resize(ref uncompressedBuffer, (int)uncompressedBufferSize);
            }

            return(uncompressedBuffer);
        }
        /// <summary>
        /// Decompresses data with <paramref name="size"/> at <paramref name="offset"/> in <paramref name="memory"/> using this <see cref="ZstdDecompressionContext"/>
        /// </summary>
        /// <param name="memory">The compressed data buffer</param>
        /// <param name="offset">The offset of the compressed data</param>
        /// <param name="size">The size of the compressed data</param>
        /// <param name="uncompressedSize">Uncompressed size of <paramref name="buffer"/></param>
        /// <returns>The uncompressed buffer</returns>
        /// <remarks>If you do not know the uncompressed size then it is recommended to use <see cref="ZstdStream"/></remarks>
        public Memory <byte> Decompress(ReadOnlyMemory <byte> memory, int offset, int size, int uncompressedSize)
        {
            Zstd.ValidateDecompressionArguments(memory.Length, offset, size, uncompressedSize);

            // Allocate uncompressed buffer
            byte[] uncompressedBuffer = new byte[uncompressedSize];

            // Get handles to buffers
            using MemoryHandle compressedBufferHandle   = memory.Pin();
            using MemoryHandle uncompressedBufferHandle = uncompressedBuffer.AsMemory().Pin();

            unsafe
            {
                // Get pointers from handles
                IntPtr compressedBufferPointer   = (IntPtr)compressedBufferHandle.Pointer;
                IntPtr uncompressedBufferPointer = (IntPtr)uncompressedBufferHandle.Pointer;

                Size uncompressedBufferSize;
                if (this.Dictionary == null)
                {
                    uncompressedBufferSize = Native.ZSTD_decompressDCtx(
                        this._context,
                        uncompressedBufferPointer, (Size)uncompressedSize,
                        compressedBufferPointer + offset, (Size)size);
                }
                else
                {
                    uncompressedBufferSize = Native.ZSTD_decompress_usingDDict(
                        this._context,
                        uncompressedBufferPointer, (Size)uncompressedSize,
                        compressedBufferPointer + offset, (Size)size,
                        this.Dictionary.GetDecompressionDictionary());
                }


                // Check for errors
                Zstd.ThrowOnError(uncompressedBufferSize);

                return(uncompressedBuffer.AsMemory(0, (int)uncompressedBufferSize));
            }
        }
Beispiel #7
0
 /// <summary>
 /// Resets this <see cref="ZstdCompressionContext"/>
 /// </summary>
 public void Reset(ZstdResetDirective resetDirective)
 {
     Zstd.ThrowOnError(Native.ZSTD_CCtx_reset(this._context, resetDirective));
 }
Beispiel #8
0
        // ------------ PARAMETERS ------------ \\

        /// <summary>
        /// Sets a parameter value inside of this <see cref="ZstdCompressionContext"/>
        /// </summary>
        /// <param name="parameter">The parameter to set</param>
        /// <param name="value">The value of the parameter</param>
        /// <remarks>
        /// <paramref name="value"/> need to be in a valid range or else it will get clamped,
        /// use <see cref="GetParameterBounds(ZstdCompressionParameter)"/> to get a valid range for a parameter
        /// </remarks>
        public void SetParameter(ZstdCompressionParameter parameter, int value)
        {
            Zstd.ThrowOnError(Native.ZSTD_CCtx_setParameter(this._context, parameter, value));
        }