diff --git a/AudioCodecsDotNet/AudioCodecsDotNet.cs b/AudioCodecsDotNet/AudioCodecsDotNet.cs index 2791038..3be1f7f 100644 --- a/AudioCodecsDotNet/AudioCodecsDotNet.cs +++ b/AudioCodecsDotNet/AudioCodecsDotNet.cs @@ -251,7 +251,7 @@ namespace AudioCodecsDotNet public class WAVReader : IAudioSource { - FileStream _fs; + Stream _IO; BinaryReader _br; ulong _dataOffset, _dataLen; ulong _samplePos, _sampleLen; @@ -260,12 +260,11 @@ namespace AudioCodecsDotNet string _path; private byte[] _sampleBuffer; - public WAVReader(string path) + public WAVReader(string path, Stream IO) { _path = path; - //_fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read); - _fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read, 0x10000, FileOptions.SequentialScan); - _br = new BinaryReader(_fs); + _IO = IO != null ? IO : new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read, 0x10000, FileOptions.SequentialScan); + _br = new BinaryReader(_IO); ParseHeaders(); @@ -275,10 +274,12 @@ namespace AudioCodecsDotNet public void Close() { - _br.Close(); - - _br = null; - _fs = null; + if (_br != null) + { + _br.Close(); + _br = null; + } + _IO = null; } private void ParseHeaders() @@ -310,7 +311,7 @@ namespace AudioCodecsDotNet foundFormat = false; foundData = false; - while (_fs.Position < fileEnd) + while (_IO.Position < fileEnd) { uint ckID, ckSize, ckSizePadded; long ckEnd; @@ -318,7 +319,7 @@ namespace AudioCodecsDotNet ckID = _br.ReadUInt32(); ckSize = _br.ReadUInt32(); ckSizePadded = (ckSize + 1U) & ~1U; - ckEnd = _fs.Position + (long)ckSizePadded; + ckEnd = _IO.Position + (long)ckSizePadded; if (ckID == fccFormat) { @@ -338,15 +339,15 @@ namespace AudioCodecsDotNet { foundData = true; - _dataOffset = (ulong)_fs.Position; - if (_fs.Length <= maxFileSize) + _dataOffset = (ulong)_IO.Position; + if (_IO.Length <= maxFileSize) { _dataLen = ckSize; } else { _largeFile = true; - _dataLen = ((ulong)_fs.Length) - _dataOffset; + _dataLen = ((ulong)_IO.Length) - _dataOffset; } } @@ -355,7 +356,7 @@ namespace AudioCodecsDotNet break; } - _fs.Seek(ckEnd, SeekOrigin.Begin); + _IO.Seek(ckEnd, SeekOrigin.Begin); } if ((foundFormat & foundData) == false) @@ -401,7 +402,7 @@ namespace AudioCodecsDotNet } seekPos = _dataOffset + (_samplePos * (uint)_blockAlign); - _fs.Seek((long)seekPos, SeekOrigin.Begin); + _IO.Seek((long)seekPos, SeekOrigin.Begin); } } @@ -480,7 +481,7 @@ namespace AudioCodecsDotNet int byteCount = (int) sampleCount * _blockAlign; if (_sampleBuffer == null || _sampleBuffer.Length < byteCount) _sampleBuffer = new byte[byteCount]; - if (_fs.Read(_sampleBuffer, 0, (int)byteCount) != byteCount) + if (_IO.Read(_sampleBuffer, 0, (int)byteCount) != byteCount) throw new Exception("Incomplete file read."); AudioCodecsDotNet.BytesToFLACSamples_16 (_sampleBuffer, 0, buff, 0, sampleCount, _channelCount); @@ -493,7 +494,7 @@ namespace AudioCodecsDotNet public class WAVWriter : IAudioDest { - FileStream _fs; + FileStream _IO; BinaryWriter _bw; int _bitsPerSample, _channelCount, _sampleRate, _blockAlign; long _sampleLen; @@ -508,8 +509,8 @@ namespace AudioCodecsDotNet _sampleRate = sampleRate; _blockAlign = _channelCount * ((_bitsPerSample + 7) / 8); - _fs = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.Read); - _bw = new BinaryWriter(_fs); + _IO = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.Read); + _bw = new BinaryWriter(_IO); WriteHeaders(); } @@ -571,7 +572,7 @@ namespace AudioCodecsDotNet _bw.Close(); _bw = null; - _fs = null; + _IO = null; } public long Position @@ -597,7 +598,7 @@ namespace AudioCodecsDotNet _sampleBuffer = new byte[sampleCount * _blockAlign]; AudioCodecsDotNet.FLACSamplesToBytes(buff, 0, _sampleBuffer, 0, sampleCount, _channelCount, _bitsPerSample); - _fs.Write(_sampleBuffer, 0, (int)sampleCount * _blockAlign); + _IO.Write(_sampleBuffer, 0, (int)sampleCount * _blockAlign); _sampleLen += sampleCount; } diff --git a/CUEToolsLib/AudioReadWrite.cs b/CUEToolsLib/AudioReadWrite.cs index bf987b2..3c3636c 100644 --- a/CUEToolsLib/AudioReadWrite.cs +++ b/CUEToolsLib/AudioReadWrite.cs @@ -13,10 +13,10 @@ namespace CUEToolsLib { public static IAudioSource GetAudioSource(string path) { switch (Path.GetExtension(path).ToLower()) { case ".wav": - return new WAVReader(path); + return new WAVReader(path, null); #if !MONO case ".flac": - return new FLACReader(path); + return new FLACReader(path, null); case ".wv": return new WavPackReader(path); case ".ape": @@ -32,6 +32,8 @@ namespace CUEToolsLib { { switch (Path.GetExtension(path).ToLower()) { + case ".wav": + return new WAVReader(path, IO); #if !MONO case ".flac": return new FLACReader(path, IO); @@ -70,12 +72,6 @@ namespace CUEToolsLib { int[,] _sampleBuffer; uint _bufferOffset, _bufferLength; - public FLACReader(string path) { - _flacReader = new FLACDotNet.FLACReader(path, null); - _bufferOffset = 0; - _bufferLength = 0; - } - public FLACReader(string path, Stream IO) { _flacReader = new FLACDotNet.FLACReader(path, IO); diff --git a/UnRarDotNet/RarStream.cs b/UnRarDotNet/RarStream.cs index a1ea2d8..5cdb975 100644 --- a/UnRarDotNet/RarStream.cs +++ b/UnRarDotNet/RarStream.cs @@ -20,6 +20,7 @@ namespace UnRarDotNet _buffer = null; _offset = 0; _length = 0; + _pos = 0; _unrar.PasswordRequired += new PasswordRequiredHandler(unrar_PasswordRequired); _unrar.DataAvailable += new DataAvailableHandler(unrar_DataAvailable); _unrar.Open(archive, Unrar.OpenMode.Extract); @@ -35,7 +36,7 @@ namespace UnRarDotNet } public override bool CanSeek { - get { return false; } + get { return true; } } public override bool CanWrite { @@ -43,11 +44,21 @@ namespace UnRarDotNet } public override long Length { - get { throw new NotSupportedException(); } + get + { + lock (this) + { + while (_size == null && !_stop) + Monitor.Wait(this); + } + if (_size == null) + throw new NotSupportedException(); + return _size.Value; + } } public override long Position { - get { throw new NotSupportedException(); } + get { return _pos; } set { Seek(value, SeekOrigin.Begin); } } public override void Close() @@ -57,9 +68,16 @@ namespace UnRarDotNet _stop = true; Monitor.Pulse(this); } - _workThread.Join(); - _workThread = null; - _unrar.Close(); + if (_workThread != null) + { + _workThread.Join(); + _workThread = null; + } + if (_unrar != null) + { + _unrar.Close(); + _unrar = null; + } base.Close(); } public override void Flush() @@ -81,16 +99,34 @@ namespace UnRarDotNet Monitor.Wait(this); if (_buffer == null) return total; + if (_seek_to != null) + { + if (_seek_to.Value < _pos) + throw new NotSupportedException(); + if (_length <= _seek_to.Value - _pos) + { + _pos += _length; + _buffer = null; + Monitor.Pulse(this); + continue; + } + _offset += (int)(_seek_to.Value - _pos); + _length -= (int)(_seek_to.Value - _pos); + _pos = _seek_to.Value; + _seek_to = null; + } if (_length > count) { Array.Copy(_buffer, _offset, array, offset, count); total += count; + _pos += count; _offset += count; _length -= count; return total; } Array.Copy(_buffer, _offset, array, offset, _length); total += _length; + _pos += _length; offset += _length; count -= _length; _buffer = null; @@ -101,7 +137,31 @@ namespace UnRarDotNet } public override long Seek(long offset, SeekOrigin origin) { - throw new NotSupportedException(); + lock (this) + { + while (_size == null && !_stop) + Monitor.Wait(this); + if (_size == null) + throw new NotSupportedException(); + switch (origin) + { + case SeekOrigin.Begin: + _seek_to = offset; + break; + case SeekOrigin.Current: + _seek_to = _pos + offset; + break; + case SeekOrigin.End: + _seek_to = _size.Value + offset; + break; + } + if (_seek_to.Value == _pos) + { + _seek_to = null; + return _pos; + } + return _seek_to.Value; + } } public override void Write(byte[] array, int offset, int count) { @@ -114,6 +174,9 @@ namespace UnRarDotNet private bool _stop; private byte[] _buffer; int _offset, _length; + long? _size; + long? _seek_to; + long _pos; private void unrar_PasswordRequired(object sender, PasswordRequiredEventArgs e) { @@ -149,13 +212,12 @@ namespace UnRarDotNet { if (_unrar.CurrentFile.FileName == _fileName) { - // unrar.CurrentFile.UnpackedSize; - _unrar.Test(); lock (this) { - _stop = true; + _size = _unrar.CurrentFile.UnpackedSize; Monitor.Pulse(this); } + _unrar.Test(); break; } else @@ -165,6 +227,11 @@ namespace UnRarDotNet //catch (StopExtractionException) //{ //} + lock (this) + { + _stop = true; + Monitor.Pulse(this); + } } } }