/// <summary> /// Reads bytes from stream. /// </summary> /// <param name="buffer"> /// The buffer into which to read the data. /// </param> /// <param name="offset"> /// The offset at which to start writing the data. /// </param> /// <param name="count"> /// The number of bytes to read. /// </param> /// <returns>byte read or -1 on end of stream.</returns> public unsafe override int Read(byte[] buffer, int offset, int count) { Verify.NotDisposed(this); // Make sure data is available in the output buffer. while ((int)this.lzmaStream.AvailOut == BufSize - this.outbufProcessed) { LzmaAction action = LzmaAction.Run; if (this.lzmaStream.AvailOut == 0) { this.lzmaStream.AvailOut = BufSize; this.lzmaStream.NextOut = (byte *)this.outbuf; this.outbufProcessed = 0; } if (this.lzmaStream.AvailIn == 0) { Span <byte> inputBuffer = new Span <byte>((void *)this.inbuf, BufSize); this.lzmaStream.AvailIn = (uint)this.innerStream.Read(inputBuffer); this.lzmaStream.NextIn = (byte *)this.inbuf; if (this.lzmaStream.AvailIn == 0) { action = LzmaAction.Finish; } } // Decode the data. var ret = NativeMethods.lzma_code(ref this.lzmaStream, action); if (ret == LzmaResult.StreamEnd) { break; } else if (ret != LzmaResult.OK) { NativeMethods.lzma_end(ref this.lzmaStream); LzmaException.ThrowOnError(ret); } } // Get the amount of data which can be copied var canRead = Math.Min( BufSize - (int)this.lzmaStream.AvailOut - this.outbufProcessed, count); var source = new Span <byte>((byte *)this.outbuf + this.outbufProcessed, canRead); var target = new Span <byte>(buffer, offset, canRead); source.CopyTo(target); this.outbufProcessed += canRead; this.position += canRead; return(canRead); }
internal static extern LzmaReturn lzma_code(ref LzmaStream stream, LzmaAction action);
internal static LzmaReturn lzma_code(ref LzmaStream stream, LzmaAction action) => IntPtr.Size > 4 ? X64.lzma_code(ref stream, action) : X86.lzma_code(ref stream, action);
public static LzmaResult lzma_code(ref LzmaStream stream, LzmaAction action) => lzma_code_ptr(ref stream, action);
public unsafe int Read(Span <byte> span) #endif { // For Decompress if (_mode != Mode.Decompress) { throw new NotSupportedException("Read() not supported on compression"); } if (_workBufPos == ReadDone) { return(0); } int readSize = 0; LzmaAction action = LzmaAction.Run; fixed(byte *readPtr = _workBuf) fixed(byte *writePtr = span) { _lzmaStream.NextIn = readPtr + _workBufPos; _lzmaStream.NextOut = writePtr; _lzmaStream.AvailOut = (uint)span.Length; while (_lzmaStream.AvailOut != 0) { if (_lzmaStream.AvailIn == 0) { // Read from _baseStream int baseReadSize = BaseStream.Read(_workBuf, 0, _workBuf.Length); TotalIn += baseReadSize; _workBufPos = 0; _lzmaStream.NextIn = readPtr; _lzmaStream.AvailIn = (uint)baseReadSize; if (baseReadSize == 0) // End of stream { action = LzmaAction.Finish; } } ulong bakAvailIn = _lzmaStream.AvailIn; ulong bakAvailOut = _lzmaStream.AvailOut; LzmaRet ret = XZInit.Lib.LzmaCode(_lzmaStream, action); _workBufPos += (int)(bakAvailIn - _lzmaStream.AvailIn); readSize += (int)(bakAvailOut - _lzmaStream.AvailOut); // Once everything has been decoded successfully, the return value of lzma_code() will be LZMA_STREAM_END. if (ret == LzmaRet.StreamEnd) { _workBufPos = ReadDone; break; } // Normally the return value of lzma_code() will be LZMA_OK until everything has been encoded. XZException.CheckReturnValue(ret); } } TotalOut += readSize; return(readSize); }