123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129 |
- using System;
- using System.IO;
- using SharpCompress.Common.Rar.Headers;
- namespace SharpCompress.Compressors.Rar
- {
- internal class RarStream : Stream
- {
- private readonly IRarUnpack unpack;
- private readonly FileHeader fileHeader;
- private readonly Stream readStream;
- private bool fetch;
- private byte[] tmpBuffer = new byte[65536];
- private int tmpOffset;
- private int tmpCount;
- private byte[] outBuffer;
- private int outOffset;
- private int outCount;
- private int outTotal;
- private bool isDisposed;
- public RarStream(IRarUnpack unpack, FileHeader fileHeader, Stream readStream)
- {
- this.unpack = unpack;
- this.fileHeader = fileHeader;
- this.readStream = readStream;
- fetch = true;
- unpack.DoUnpack(fileHeader, readStream, this);
- fetch = false;
- }
- protected override void Dispose(bool disposing)
- {
- if (!isDisposed) {
- isDisposed = true;
- base.Dispose(disposing);
- readStream.Dispose();
- }
- }
- public override bool CanRead => true;
- public override bool CanSeek => false;
- public override bool CanWrite => false;
- public override void Flush()
- {
- }
- public override long Length => fileHeader.UncompressedSize;
- public override long Position { get => fileHeader.UncompressedSize - unpack.DestSize; set => throw new NotSupportedException(); }
- public override int Read(byte[] buffer, int offset, int count)
- {
- outTotal = 0;
- if (tmpCount > 0)
- {
- int toCopy = tmpCount < count ? tmpCount : count;
- Buffer.BlockCopy(tmpBuffer, tmpOffset, buffer, offset, toCopy);
- tmpOffset += toCopy;
- tmpCount -= toCopy;
- offset += toCopy;
- count -= toCopy;
- outTotal += toCopy;
- }
- if (count > 0 && unpack.DestSize > 0)
- {
- outBuffer = buffer;
- outOffset = offset;
- outCount = count;
- fetch = true;
- unpack.DoUnpack();
- fetch = false;
- }
- return outTotal;
- }
- public override long Seek(long offset, SeekOrigin origin)
- {
- throw new NotSupportedException();
- }
- public override void SetLength(long value)
- {
- throw new NotSupportedException();
- }
- public override void Write(byte[] buffer, int offset, int count)
- {
- if (!fetch)
- {
- throw new NotSupportedException();
- }
- if (outCount > 0)
- {
- int toCopy = outCount < count ? outCount : count;
- Buffer.BlockCopy(buffer, offset, outBuffer, outOffset, toCopy);
- outOffset += toCopy;
- outCount -= toCopy;
- offset += toCopy;
- count -= toCopy;
- outTotal += toCopy;
- }
- if (count > 0)
- {
- if (tmpBuffer.Length < tmpCount + count)
- {
- byte[] newBuffer =
- new byte[tmpBuffer.Length * 2 > tmpCount + count ? tmpBuffer.Length * 2 : tmpCount + count];
- Buffer.BlockCopy(tmpBuffer, 0, newBuffer, 0, tmpCount);
- tmpBuffer = newBuffer;
- }
- Buffer.BlockCopy(buffer, offset, tmpBuffer, tmpCount, count);
- tmpCount += count;
- tmpOffset = 0;
- unpack.Suspended = true;
- }
- else
- {
- unpack.Suspended = false;
- }
- }
- }
- }
|