Esempio n. 1
0
        protected override void Dispose(bool disposing)
        {
            if (_stream == null)
            {
                return;
            }

            var _lzma_stream = new lzma_stream();

            _lzma_stream.next_in   = next_in;
            _lzma_stream.next_out  = next_out;
            _lzma_stream.avail_in  = avail_in;
            _lzma_stream.avail_out = avail_out;
            _lzma_stream.allocator = allocator;
            _lzma_stream._internal = _internal;
            _lzma_stream.total_in  = total_in;
            _lzma_stream.total_out = total_out;

            ManagedXZPInvoke.lzma_end(&_lzma_stream);

            Marshal.FreeHGlobal(_inbuf);
            Marshal.FreeHGlobal(_outbuf);
            //_stream.Close();
            _stream.Dispose();
            _stream = null;
        }
Esempio n. 2
0
        private void Init()
        {
            _inbuf  = Marshal.AllocHGlobal(BUFSIZE);
            _outbuf = Marshal.AllocHGlobal(BUFSIZE);

            var _lzma_stream = new lzma_stream();

            var r = ManagedXZPInvoke.lzma_auto_decoder(&_lzma_stream, ulong.MaxValue, LZMA_CONCATENATED);

            if (r != lzma_ret.LZMA_OK)
            {
                throw new Exception($"Can not create lzma stream: {r}");
            }

            // init lzma_stream
            next_in   = _inbuf;
            next_out  = _outbuf;
            avail_in  = UIntPtr.Zero;
            avail_out = (UIntPtr)BUFSIZE;
            allocator = _lzma_stream.allocator;
            _internal = _lzma_stream._internal;
            total_in  = _lzma_stream.total_in;
            total_out = _lzma_stream.total_out;
        }
Esempio n. 3
0
        /// <summary>
        /// learn from 02_decompress.c
        /// </summary>
        /// <param name="buffer"></param>
        /// <param name="offset"></param>
        /// <param name="count"></param>
        /// <returns></returns>
        public override int Read(byte[] buffer, int offset, int count)
        {
            if (buffer == null)
            {
                throw new ArgumentNullException(nameof(buffer));
            }
            if (offset < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(offset));
            }
            if (count < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(count));
            }
            if (count + offset > buffer.Length)
            {
                throw new ArgumentOutOfRangeException(nameof(count), "offset+count > buffer.length");
            }
            if (count == 0)
            {
                return(0);
            }

            int cTotalRead = 0;

            while (true)
            {
                // read from underlying stream
                if (avail_in == UIntPtr.Zero && action == lzma_action.LZMA_RUN)
                {
                    // read more data from underlying stream
                    var data      = new byte[BUFSIZE];
                    var bytesRead = _stream.Read(data, 0, BUFSIZE);
                    if (bytesRead < BUFSIZE)
                    {
                        action = lzma_action.LZMA_FINISH;                      // source stream has no more data
                    }
                    next_in  = _inbuf;
                    avail_in = (UIntPtr)bytesRead;
                    Marshal.Copy(data, 0, _inbuf, bytesRead);
                }

                // try to read from existing outbuf
                int cReadable = BUFSIZE - (int)(uint)avail_out - read_pos;
                if (cReadable > 0)
                {
                    var cCopy = Math.Min(cReadable, count - cTotalRead);
                    var p     = (IntPtr.Size == 8) ? new IntPtr(_outbuf.ToInt64() + read_pos) : new IntPtr(_outbuf.ToInt32() + read_pos);
                    Marshal.Copy(p, buffer, offset + cTotalRead, cCopy);
                    cTotalRead += cCopy;
                    read_pos   += cCopy;
                    //Trace.Assert(cTotalRead <= count);
                    if (cTotalRead == count)
                    {
                        return(cTotalRead);
                    }
                }

                // need to read more data from outbuf
                // if previous decode returns LZMA_STREAM_END, there will be no more data
                if (ret == lzma_ret.LZMA_STREAM_END)
                {
                    return(cTotalRead);
                }

                // otherwise, reset outbuf to recv more decompressed data from liblzma, or decompress is finished
                //Trace.Assert(read_pos + (uint)_lzma_stream.avail_out <= BUFSIZE);
                if (avail_out == UIntPtr.Zero && read_pos + (uint)avail_out == BUFSIZE)
                {
                    next_out  = _outbuf;
                    avail_out = (UIntPtr)BUFSIZE;
                    read_pos  = 0;
                }

                var _lzma_stream = new lzma_stream();
                _lzma_stream.next_in   = next_in;
                _lzma_stream.next_out  = next_out;
                _lzma_stream.avail_in  = avail_in;
                _lzma_stream.avail_out = avail_out;
                _lzma_stream.allocator = allocator;
                _lzma_stream._internal = _internal;
                _lzma_stream.total_in  = total_in;
                _lzma_stream.total_out = total_out;

                // do decompress
                ret = ManagedXZPInvoke.lzma_code(&_lzma_stream, action);
                if (ret != lzma_ret.LZMA_OK && ret != lzma_ret.LZMA_STREAM_END)
                {
                    throw new Exception($"lzma_code returns {ret}");
                }

                next_in   = _lzma_stream.next_in;
                next_out  = _lzma_stream.next_out;
                avail_in  = _lzma_stream.avail_in;
                avail_out = _lzma_stream.avail_out;
                allocator = _lzma_stream.allocator;
                _internal = _lzma_stream._internal;
                total_in  = _lzma_stream.total_in;
                total_out = _lzma_stream.total_out;
            }
        }