Files
cuetools.net/UnRarDotNet/RarStream.cs

171 lines
3.6 KiB
C#
Raw Normal View History

using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Threading;
/* Author: Gregory S. Chudov
*
*/
namespace UnRarDotNet
{
public class RarStream : Stream
{
public RarStream(string archive, string fileName)
{
_stop = false;
_unrar = new Unrar();
_buffer = null;
_offset = 0;
_length = 0;
_unrar.PasswordRequired += new PasswordRequiredHandler(unrar_PasswordRequired);
_unrar.DataAvailable += new DataAvailableHandler(unrar_DataAvailable);
_unrar.Open(archive, Unrar.OpenMode.Extract);
_fileName = fileName;
_workThread = new Thread(Decompress);
_workThread.Priority = ThreadPriority.BelowNormal;
_workThread.IsBackground = true;
_workThread.Start(null);
}
public override bool CanRead
{
get { return true; }
}
public override bool CanSeek
{
get { return false; }
}
public override bool CanWrite
{
get { return false; }
}
public override long Length
{
get { throw new NotSupportedException(); }
}
public override long Position
{
get { throw new NotSupportedException(); }
set { Seek(value, SeekOrigin.Begin); }
}
public override void Close()
{
lock (this)
{
_stop = true;
Monitor.Pulse(this);
}
_workThread.Join();
_workThread = null;
_unrar.Close();
base.Close();
}
public override void Flush()
{
throw new NotSupportedException();
}
public override void SetLength(long value)
{
throw new NotSupportedException();
}
public override int Read(byte[] array, int offset, int count)
{
int total = 0;
while (count > 0)
{
lock (this)
{
while (_buffer == null && !_stop)
Monitor.Wait(this);
if (_buffer == null)
return total;
if (_length > count)
{
Array.Copy(_buffer, _offset, array, offset, count);
total += count;
_offset += count;
_length -= count;
return total;
}
Array.Copy(_buffer, _offset, array, offset, _length);
total += _length;
offset += _length;
count -= _length;
_buffer = null;
Monitor.Pulse(this);
}
}
return total;
}
public override long Seek(long offset, SeekOrigin origin)
{
throw new NotSupportedException();
}
public override void Write(byte[] array, int offset, int count)
{
throw new NotSupportedException();
}
private Unrar _unrar;
private string _fileName;
private Thread _workThread;
private bool _stop;
private byte[] _buffer;
int _offset, _length;
private void unrar_PasswordRequired(object sender, PasswordRequiredEventArgs e)
{
e.Password = "PARS";
e.ContinueOperation = true;
}
private void unrar_DataAvailable(object sender, DataAvailableEventArgs e)
{
lock (this)
{
while (_buffer != null && !_stop)
Monitor.Wait(this);
if (_stop)
{
e.ContinueOperation = false;
Monitor.Pulse(this);
return;
}
_buffer = e.Data;
_length = _buffer.Length;
_offset = 0;
e.ContinueOperation = true;
Monitor.Pulse(this);
}
}
private void Decompress(object o)
{
//try
{
while (_unrar.ReadHeader())
{
if (_unrar.CurrentFile.FileName == _fileName)
{
// unrar.CurrentFile.UnpackedSize;
_unrar.Test();
lock (this)
{
_stop = true;
Monitor.Pulse(this);
}
break;
}
else
_unrar.Skip();
}
}
//catch (StopExtractionException)
//{
//}
}
}
}