/// <summary> /// Reads data from the buffer or the underlying stream. /// </summary> /// <param name="userBuffer">The buffer to read the data to.</param> /// <param name="offset">The offset in the buffer to write to.</param> /// <param name="count">The number of bytes to read.</param> /// <returns>The number of bytes actually read.</returns> public override int Read(byte[] userBuffer, int offset, int count) { ExceptionUtils.CheckArgumentNotNull(userBuffer, "userBuffer"); ExceptionUtils.CheckIntegerNotNegative(offset, "offset"); ExceptionUtils.CheckIntegerPositive(count, "count"); int bytesRead = 0; // See whether we still have buffered data and read from it if we have; // NOTE When not reading from the buffer the currentReadNode must be null. while (this.currentReadNode != null && count > 0) { byte[] currentBytes = this.currentReadNode.Value; int bytesInCurrentBuffer = currentBytes.Length - this.positionInCurrentBuffer; if (bytesInCurrentBuffer == count) { // Copy all the remaining bytes of the current buffer to the user buffer // and move to the next buffer Buffer.BlockCopy(currentBytes, this.positionInCurrentBuffer, userBuffer, offset, count); bytesRead += count; this.MoveToNextBuffer(); return(bytesRead); } if (bytesInCurrentBuffer > count) { // Copy the requested number of bytes to the user buffer // and update the position in the current buffer Buffer.BlockCopy(currentBytes, this.positionInCurrentBuffer, userBuffer, offset, count); bytesRead += count; this.positionInCurrentBuffer += count; return(bytesRead); } // Copy the remaining bytes of the current buffer to the user buffer and // move to the next buffer Buffer.BlockCopy(currentBytes, this.positionInCurrentBuffer, userBuffer, offset, bytesInCurrentBuffer); bytesRead += bytesInCurrentBuffer; offset += bytesInCurrentBuffer; count -= bytesInCurrentBuffer; this.MoveToNextBuffer(); } // When we get here we either could not satisfy the requested number of bytes // from the buffers or are in buffering mode. Debug.Assert(this.currentReadNode == null, "No current read node should exist if we are not working off the buffers."); int bytesReadFromInnerStream = this.innerStream.Read(userBuffer, offset, count); // If we are in buffering mode, store the read bytes in our buffer if (!this.bufferingModeDisabled && bytesReadFromInnerStream > 0) { byte[] newDataBuffer = new byte[bytesReadFromInnerStream]; Buffer.BlockCopy(userBuffer, offset, newDataBuffer, 0, bytesReadFromInnerStream); this.buffers.AddLast(newDataBuffer); } return(bytesRead + bytesReadFromInnerStream); }