示例#1
0
        /// <summary>
        /// Compress data in-memory
        /// </summary>
        /// <param name="data"></param>
        /// <param name="offset"></param>
        /// <param name="count"></param>
        /// <param name="threads"></param>
        /// <param name="level">0-9, default is 6, bigger number needs more time and produces smaller compressed data</param>
        /// <returns></returns>
        public static byte[] CompressBytes(byte[] data, int offset, int count, int threads = 1, int level = 6)
        {
            if (data == null)
            {
                throw new ArgumentNullException(nameof(data));
            }
            if (offset < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(offset));
            }
            if (count < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(count));
            }
            if (count + offset > data.Length)
            {
                throw new ArgumentOutOfRangeException(nameof(count), "offset+count > data.length");
            }
            if (level < 0 || level > 9)
            {
                throw new ArgumentOutOfRangeException(nameof(level));
            }

            var _lzma_stream = new lzma_stream();
            var ret          = CreateEncoder(_lzma_stream, threads, (uint)level);

            if (ret == lzma_ret.LZMA_OK)
            {
                var compressed = CodeBuffer(_lzma_stream, data, offset, count);
                Native.lzma_end(_lzma_stream);
                return(compressed);
            }

            throw new Exception($"Can not create lzma stream: {ret}");
        }
示例#2
0
        public static byte[] DecompressBytes(byte[] data, int offset, int count)
        {
            if (data == null)
            {
                throw new ArgumentNullException(nameof(data));
            }
            if (offset < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(offset));
            }
            if (count < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(count));
            }
            if (count + offset > data.Length)
            {
                throw new ArgumentOutOfRangeException(nameof(count), "offset+count > data.length");
            }

            var _lzma_stream = new lzma_stream();
            var ret          = Native.lzma_auto_decoder(_lzma_stream, ulong.MaxValue, Native.LZMA_CONCATENATED);

            if (ret == lzma_ret.LZMA_OK)
            {
                var decompressed = CodeBuffer(_lzma_stream, data, offset, count);
                Native.lzma_end(_lzma_stream);
                return(decompressed);
            }

            throw new Exception($"Can not create lzma stream: {ret}");
        }
示例#3
0
 protected override void Dispose(bool disposing)
 {
     if (_stream == null)
     {
         return;
     }
     Native.lzma_end(_lzma_stream);
     Marshal.FreeHGlobal(_inbuf);
     Marshal.FreeHGlobal(_outbuf);
     _stream.Close();
     _stream = null;
 }
示例#4
0
        protected override void Dispose(bool disposing)
        {
            if (_stream == null)
            {
                return;
            }
            try
            {
                // compress all remaining data
                while (true)
                {
                    // do compress, LZMA_FINISH action should return LZMA_OK or LZMA_STREAM_END on success
                    var ret = Native.lzma_code(_lzma_stream, lzma_action.LZMA_FINISH);
                    if (ret != lzma_ret.LZMA_STREAM_END && ret != lzma_ret.LZMA_OK)
                    {
                        throw new Exception($"lzma_code returns {ret}");
                    }

                    // write output buffer to underlying stream
                    if (_lzma_stream.avail_out == UIntPtr.Zero || ret == lzma_ret.LZMA_STREAM_END)
                    {
                        int size = (int)(BUFSIZE - (uint)_lzma_stream.avail_out);
                        var data = ArrayPool <byte> .Shared.Rent(size);

                        Marshal.Copy(_outbuf, data, 0, size);
                        _stream.Write(data, 0, size);
                        ArrayPool <byte> .Shared.Return(data);

                        // Reset next_out and avail_out.
                        _lzma_stream.next_out  = _outbuf;
                        _lzma_stream.avail_out = (UIntPtr)BUFSIZE;
                    }

                    if (ret == lzma_ret.LZMA_STREAM_END)
                    {
                        break;
                    }
                }
            }
            finally
            {
                Native.lzma_end(_lzma_stream);
                Marshal.FreeHGlobal(_inbuf);
                Marshal.FreeHGlobal(_outbuf);
                _stream.Close();
                _stream = null;
            }
        }