Пример #1
0
        /// <summary>
        /// Decompresses data. Uses <see cref="BrotliDecoder"/>.
        /// </summary>
        /// <returns>Decompressed data.</returns>
        /// <param name="compressed">Compressed data.</param>
        /// <exception cref="ArgumentException">Invalid data.</exception>
        /// <exception cref="OutOfMemoryException"></exception>
        public static unsafe byte[] BrotliDecompress(ReadOnlySpan <byte> compressed)
        {
            int n = checked (compressed.Length * 4 + 8000);

            for (int i = 0; i < 3; i++)
            {
                if (n < 512_000)
                {
                    n *= 2;
                }
            }
            //print.it(compressed.Length, n, n/compressed.Length); //usually ~ 80 KB
            for (; ; n = checked (n * 2))
            {
                byte *b = null;
                try {
                    b = MemoryUtil.Alloc(n);
                    if (BrotliDecoder.TryDecompress(compressed, new(b, n), out int nw))
                    {
                        return(new Span <byte>(b, nw).ToArray());
                    }
                    if (nw == 0)
                    {
                        throw new ArgumentException("cannot decompress this data");
                    }
                    //print.it(n);
                }
                finally { MemoryUtil.Free(b); }
            }
        }
Пример #2
0
        /// <summary>
        /// Compresses data. Uses <see cref="BrotliEncoder"/>.
        /// </summary>
        /// <param name="data">Data. See also: <see cref="MemoryMarshal.AsBytes"/>, <see cref="CollectionsMarshal.AsSpan"/>.</param>
        /// <param name="level">Compression level, 0 (no compression) to 11 (maximal compression). Default 6. Bigger levels don't make much smaller but can make much slower.</param>
        /// <exception cref="ArgumentOutOfRangeException">Invalid <i>level</i>.</exception>
        /// <exception cref="OutOfMemoryException"></exception>
        public static unsafe byte[] BrotliCompress(ReadOnlySpan <byte> data, int level = 6)
        {
            int n = BrotliEncoder.GetMaxCompressedLength(data.Length);
            var b = MemoryUtil.Alloc(n);

            try {
                if (!BrotliEncoder.TryCompress(data, new(b, n), out n, level, 22))
                {
                    throw new AuException();
                }
                return(new Span <byte>(b, n).ToArray());
            }
            finally { MemoryUtil.Free(b); }
        }