public override int Read(byte[] buffer, int offset, int count) { if (buffer == null) { throw new ArgumentNullException("buffer"); } if (offset + count > buffer.Length) { throw new ArgumentException("The sum of offset and count is greater than the buffer length."); } if (offset < 0 || count < 0) { throw new ArgumentOutOfRangeException("offset", "offset or count is negative."); } lock (_lock) { var totalBytesRead = 0; while (count > 0) { while (_first == null && !_isDisposed) { Monitor.Wait(_lock); } if (_first == null) { return(totalBytesRead); } var bytesRead = _first.Read(buffer, offset, count); if (_first.IsEmpty) { _first = _first.Next; } count -= bytesRead; totalBytesRead += bytesRead; offset += bytesRead; _position += bytesRead; } return(totalBytesRead); } }
private void InternalSeekForward(long offset) { while (offset > 0) { var remainingBytesInCurrentPipe = _first.Length - _first.Position; if (remainingBytesInCurrentPipe >= offset) { _first.Position += (int)offset; offset = 0; } else { _first = _first.Next; offset -= remainingBytesInCurrentPipe; } } }
public override void Write(byte[] buffer, int offset, int count) { if (buffer == null) { throw new ArgumentNullException("buffer"); } if (offset + count > buffer.Length) { throw new ArgumentException("The sum of offset and count is greater than the buffer length."); } if (offset < 0 || count < 0) { throw new ArgumentOutOfRangeException("offset", "offset or count is negative."); } if (_isDisposed) { throw CreateObjectDisposedException(); } if (count == 0) { return; } lock (_lock) { var last = new PipeEntry(buffer, offset, count); if (_last == null) { _last = last; } else { _last = _last.Next = last; } if (_first == null) { _first = _last; } _length += count; Monitor.Pulse(_lock); } }
public override void SetLength(long value) { if (value < 0) { throw new ArgumentOutOfRangeException("Cannot be negative.", nameof(value)); } if (_isDisposed) { throw CreateObjectDisposedException(); } lock (_lock) { if (value < _position) { throw new ArgumentOutOfRangeException("Cannot be less that the current position.", nameof(value)); } if (value > _length) { throw new ArgumentOutOfRangeException("Cannot be greater than the current length.", nameof(value)); } var bytesToSkip = value - _position; while (bytesToSkip > 0) { var remainingBytesInCurrentPipe = _first.Length - _first.Position; if (remainingBytesInCurrentPipe > bytesToSkip) { _first.Length = _first.Position + (int)bytesToSkip; _first.Next = null; bytesToSkip = 0; } else { _first = _first.Next; bytesToSkip -= remainingBytesInCurrentPipe; } } _length = value; } }