diff options
Diffstat (limited to 'Emby.Common.Implementations/IO/SharpCifs/Util/Sharpen/PipedInputStream.cs')
| -rw-r--r-- | Emby.Common.Implementations/IO/SharpCifs/Util/Sharpen/PipedInputStream.cs | 356 |
1 files changed, 196 insertions, 160 deletions
diff --git a/Emby.Common.Implementations/IO/SharpCifs/Util/Sharpen/PipedInputStream.cs b/Emby.Common.Implementations/IO/SharpCifs/Util/Sharpen/PipedInputStream.cs index d5004c988..d2438be70 100644 --- a/Emby.Common.Implementations/IO/SharpCifs/Util/Sharpen/PipedInputStream.cs +++ b/Emby.Common.Implementations/IO/SharpCifs/Util/Sharpen/PipedInputStream.cs @@ -3,170 +3,206 @@ using System.Threading; namespace SharpCifs.Util.Sharpen { - internal class PipedInputStream : InputStream - { - private byte[] _oneBuffer; - public const int PipeSize = 1024; - - protected byte[] Buffer; - private bool _closed; - private ManualResetEvent _dataEvent; - private int _end; - private int _start; - private object _thisLock; - private bool _allowGrow = false; - - public int In { - get { return _start; } - set { _start = value; } - } - - public int Out { - get { return _end; } - set { _end = value; } - } + internal class PipedInputStream : InputStream + { + private byte[] _oneBuffer; + public const int PipeSize = 1024; - public PipedInputStream () - { - _thisLock = new object (); - _dataEvent = new ManualResetEvent (false); - Buffer = new byte[PipeSize + 1]; - } + protected byte[] Buffer; + private bool _closed; + private ManualResetEvent _dataEvent; + private int _end; + private int _start; + private object _thisLock; + private bool _allowGrow = false; - public PipedInputStream (PipedOutputStream os): this () - { - os.Attach (this); - } + public int In + { + get { return _start; } + set { _start = value; } + } - public override void Close () - { - lock (_thisLock) { - _closed = true; - _dataEvent.Set (); - } - } + public int Out + { + get { return _end; } + set { _end = value; } + } - public override int Available () - { - lock (_thisLock) { - if (_start <= _end) { - return (_end - _start); - } - return ((Buffer.Length - _start) + _end); - } - } + public PipedInputStream() + { + _thisLock = new object(); + _dataEvent = new ManualResetEvent(false); + Buffer = new byte[PipeSize + 1]; + } - public override int Read () - { - if (_oneBuffer == null) - _oneBuffer = new byte[1]; - if (Read (_oneBuffer, 0, 1) == -1) - return -1; - return _oneBuffer[0]; - } + public PipedInputStream(PipedOutputStream os) : this() + { + os.Attach(this); + } - public override int Read (byte[] b, int offset, int len) - { - int length = 0; - do { - _dataEvent.WaitOne (); - lock (_thisLock) { - if (_closed && Available () == 0) { - return -1; - } - if (_start < _end) { - length = Math.Min (len, _end - _start); - Array.Copy (Buffer, _start, b, offset, length); - _start += length; - } else if (_start > _end) { - length = Math.Min (len, Buffer.Length - _start); - Array.Copy (Buffer, _start, b, offset, length); - len -= length; - _start = (_start + length) % Buffer.Length; - if (len > 0) { - int i = Math.Min (len, _end); - Array.Copy (Buffer, 0, b, offset + length, i); - _start += i; - length += i; - } - } - if (_start == _end && !_closed) { - _dataEvent.Reset (); - } - Monitor.PulseAll (_thisLock); - } - } while (length == 0); - return length; - } - - private int Allocate (int len) - { - int alen; - while ((alen = TryAllocate (len)) == 0) { - // Wait until somebody reads data - try { - Monitor.Wait (_thisLock); - } catch { - _closed = true; - _dataEvent.Set (); - throw; - } - } - return alen; - } - - int TryAllocate (int len) - { - int free; - if (_start <= _end) { - free = (Buffer.Length - _end) + _start; - } else { - free = _start - _end; - } - if (free <= len) { - if (!_allowGrow) - return free > 0 ? free - 1 : 0; - int sizeInc = (len - free) + 1; - byte[] destinationArray = new byte[Buffer.Length + sizeInc]; - if (_start <= _end) { - Array.Copy (Buffer, _start, destinationArray, _start, _end - _start); - } else { - Array.Copy (Buffer, 0, destinationArray, 0, _end); - Array.Copy (Buffer, _start, destinationArray, _start + sizeInc, Buffer.Length - _start); - _start += sizeInc; - } - Buffer = destinationArray; - } - return len; - } - - internal void Write (int b) - { - lock (_thisLock) { - Allocate (1); - Buffer[_end] = (byte)b; - _end = (_end + 1) % Buffer.Length; - _dataEvent.Set (); - } - } - - internal void Write (byte[] b, int offset, int len) - { - do { - lock (_thisLock) { - int alen = Allocate (len); - int length = Math.Min (Buffer.Length - _end, alen); - Array.Copy (b, offset, Buffer, _end, length); - _end = (_end + length) % Buffer.Length; - if (length < alen) { - Array.Copy (b, offset + length, Buffer, 0, alen - length); - _end += alen - length; - } - _dataEvent.Set (); - len -= alen; - offset += alen; - } - } while (len > 0); - } - } + public override void Close() + { + lock (_thisLock) + { + _closed = true; + _dataEvent.Set(); + } + } + + public override int Available() + { + lock (_thisLock) + { + if (_start <= _end) + { + return (_end - _start); + } + return ((Buffer.Length - _start) + _end); + } + } + + public override int Read() + { + if (_oneBuffer == null) + _oneBuffer = new byte[1]; + if (Read(_oneBuffer, 0, 1) == -1) + return -1; + return _oneBuffer[0]; + } + + public override int Read(byte[] b, int offset, int len) + { + int length = 0; + do + { + _dataEvent.WaitOne(); + lock (_thisLock) + { + if (_closed && Available() == 0) + { + return -1; + } + if (_start < _end) + { + length = Math.Min(len, _end - _start); + Array.Copy(Buffer, _start, b, offset, length); + _start += length; + } + else if (_start > _end) + { + length = Math.Min(len, Buffer.Length - _start); + Array.Copy(Buffer, _start, b, offset, length); + len -= length; + _start = (_start + length) % Buffer.Length; + if (len > 0) + { + int i = Math.Min(len, _end); + Array.Copy(Buffer, 0, b, offset + length, i); + _start += i; + length += i; + } + } + if (_start == _end && !_closed) + { + _dataEvent.Reset(); + } + Monitor.PulseAll(_thisLock); + } + } while (length == 0); + return length; + } + + private int Allocate(int len) + { + int alen; + while ((alen = TryAllocate(len)) == 0) + { + // Wait until somebody reads data + try + { + Monitor.Wait(_thisLock); + } + catch + { + _closed = true; + _dataEvent.Set(); + throw; + } + } + return alen; + } + + int TryAllocate(int len) + { + int free; + if (_start <= _end) + { + free = (Buffer.Length - _end) + _start; + } + else + { + free = _start - _end; + } + if (free <= len) + { + if (!_allowGrow) + return free > 0 ? free - 1 : 0; + int sizeInc = (len - free) + 1; + byte[] destinationArray = new byte[Buffer.Length + sizeInc]; + if (_start <= _end) + { + Array.Copy(Buffer, _start, destinationArray, _start, _end - _start); + } + else + { + Array.Copy(Buffer, + 0, + destinationArray, + 0, + _end); + Array.Copy(Buffer, + _start, + destinationArray, + _start + sizeInc, + Buffer.Length - _start); + _start += sizeInc; + } + Buffer = destinationArray; + } + return len; + } + + internal void Write(int b) + { + lock (_thisLock) + { + Allocate(1); + Buffer[_end] = (byte)b; + _end = (_end + 1) % Buffer.Length; + _dataEvent.Set(); + } + } + + internal void Write(byte[] b, int offset, int len) + { + do + { + lock (_thisLock) + { + int alen = Allocate(len); + int length = Math.Min(Buffer.Length - _end, alen); + Array.Copy(b, offset, Buffer, _end, length); + _end = (_end + length) % Buffer.Length; + if (length < alen) + { + Array.Copy(b, offset + length, Buffer, 0, alen - length); + _end += alen - length; + } + _dataEvent.Set(); + len -= alen; + offset += alen; + } + } while (len > 0); + } + } } |
