예제 #1
0
        /// <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);
        }
예제 #2
0
 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);
 }