/// <summary> /// When overridden in a derived class, reads a sequence of bytes from the current stream and advances the position within /// the stream by the number of bytes read. /// </summary> /// <returns> /// The total number of bytes read into the buffer. This can be less than the number of bytes requested if that many bytes /// are not currently available, or zero (0) if the end of the stream has been reached. /// </returns> /// <param name="buffer"> /// An array of bytes. When this method returns, the buffer contains the specified byte array with the /// values between <paramref name="offset" /> and (<paramref name="offset" /> + <paramref name="count" /> - 1) replaced by /// the bytes read from the current source. /// </param> /// <param name="offset"> /// The zero-based byte offset in <paramref name="buffer" /> at which to begin storing the data read /// from the current stream. /// </param> /// <param name="count">The maximum number of bytes to be read from the current stream. </param> /// <exception cref="T:System.ArgumentException"> /// The sum of <paramref name="offset" /> and <paramref name="count" /> is /// larger than the buffer length. /// </exception> /// <exception cref="T:System.ArgumentNullException"><paramref name="buffer" /> is null. </exception> /// <exception cref="T:System.ArgumentOutOfRangeException"> /// <paramref name="offset" /> or <paramref name="count" /> is /// negative. /// </exception> /// <exception cref="T:System.IO.IOException">An I/O error occurs. </exception> /// <exception cref="T:System.NotSupportedException">The stream does not support reading. </exception> /// <exception cref="T:System.ObjectDisposedException">Methods were called after the stream was closed. </exception> public override int Read(byte[] buffer, int offset, int count) { buffer.ThrowIfInvalid("buffer", b => b != null, "Buffer cannot be null."); offset.ThrowIfInvalid("offset", o => o >= 0, "Offset must be a value greater than or equal to zero."); count.ThrowIfInvalid("count", c => c >= 0, "Count must be a value greater than or equal to zero."); if (buffer.Length - offset < count) { throw new ArgumentException( String.Format( "Buffer length minus the offset must be greater than or equal to count (buffer.Length = {0}, offset = {1}, count = {2}).", buffer.Length, offset, count)); } if (this.endOfPayload) { return(0); } if (this.lineBuffer == null) { SeekPreamble(this.stream, out this.unixLineEnding); this.lineBuffer = UUEncoder.DecodeLine(this.stream); this.ReadLineEnding(); this.lineBufferIndex = 0; } int readCount = 0; int remainingCount = count; while (remainingCount > 0) { int lineBufferCount = this.lineBuffer.Length - this.lineBufferIndex; if (remainingCount >= lineBufferCount) { Array.Copy(this.lineBuffer, this.lineBufferIndex, buffer, offset + readCount, lineBufferCount); if (this.lineBuffer.Length == 0) { break; } this.lineBuffer = UUEncoder.DecodeLine(this.stream); this.ReadLineEnding(); this.lineBufferIndex = 0; readCount += lineBufferCount; remainingCount -= lineBufferCount; } else { Array.Copy(this.lineBuffer, this.lineBufferIndex, buffer, offset + readCount, remainingCount); this.lineBufferIndex += remainingCount; readCount += remainingCount; remainingCount = 0; } } if (this.lineBuffer.Length == 0) { this.endOfPayload = true; } return(readCount); }
private void FlushBuffer(byte[] buffer) { byte[] encodedBuffer = UUEncoder.EncodeLine(buffer); this.stream.Write(encodedBuffer, 0, encodedBuffer.Length); this.stream.Write(this.lineEnding, 0, this.lineEnding.Length); }