mirror of
https://github.com/adamhathcock/sharpcompress.git
synced 2026-02-13 21:22:22 +00:00
154 lines
4.3 KiB
C#
154 lines
4.3 KiB
C#
using System;
|
|
using System.IO;
|
|
using SharpCompress.Common.Rar.Headers;
|
|
|
|
namespace SharpCompress.Compressor.Rar
|
|
{
|
|
internal class RarStream : Stream
|
|
{
|
|
private readonly Unpack unpack;
|
|
private readonly FileHeader fileHeader;
|
|
private readonly Stream readStream;
|
|
|
|
private bool fetch = false;
|
|
|
|
private byte[] tmpBuffer = new byte[65536];
|
|
private int tmpOffset = 0;
|
|
private int tmpCount = 0;
|
|
|
|
private byte[] outBuffer;
|
|
private int outOffset;
|
|
private int outCount = 0;
|
|
private int outTotal;
|
|
private bool isDisposed;
|
|
|
|
public RarStream(Unpack 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)
|
|
{
|
|
return;
|
|
}
|
|
isDisposed = true;
|
|
base.Dispose(disposing);
|
|
readStream.Dispose();
|
|
}
|
|
|
|
public override bool CanRead
|
|
{
|
|
get
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
|
|
public override bool CanSeek
|
|
{
|
|
get
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public override bool CanWrite
|
|
{
|
|
get
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public override void Flush()
|
|
{
|
|
}
|
|
|
|
public override long Length
|
|
{
|
|
get { return fileHeader.UncompressedSize; }
|
|
}
|
|
|
|
public override long Position
|
|
{
|
|
get { return fileHeader.UncompressedSize - unpack.DestSize; }
|
|
set { throw new NotImplementedException(); }
|
|
}
|
|
|
|
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 NotImplementedException();
|
|
}
|
|
|
|
public override void SetLength(long value)
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
|
|
public override void Write(byte[] buffer, int offset, int count)
|
|
{
|
|
if (!fetch)
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
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;
|
|
}
|
|
}
|
|
} |