/// <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}"); }
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}"); }
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; }
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; } }