예제 #1
0
        public override int Read(byte[] buffer, int offset, int count)
        {
            if (sourceOrDestination == null)
            {
                throw new ObjectDisposedException("ConverterStream");
            }

            if (producer == null)
            {
                throw new InvalidOperationException(Strings.ReadUnsupported);
            }

            InternalDebug.Assert(producer != null);

            if (null == buffer)
            {
                throw new ArgumentNullException("buffer");
            }

            if (offset > buffer.Length || offset < 0)
            {
                throw new ArgumentOutOfRangeException("offset", Strings.OffsetOutOfRange);
            }

            if (count > buffer.Length || count < 0)
            {
                throw new ArgumentOutOfRangeException("count", Strings.CountOutOfRange);
            }

            if (count + offset > buffer.Length)
            {
                throw new ArgumentOutOfRangeException("count", Strings.CountTooLarge);
            }

            if (inconsistentState)
            {
                throw new InvalidOperationException(Strings.ConverterStreamInInconsistentStare);
            }

            InternalDebug.Assert(producer != null);

            var initialCount = count;

            if (byteSource != null)
            {
                byte[] chunkBuffer;
                int    chunkOffset;
                int    chunkCount;

                while (count != 0 && byteSource.GetOutputChunk(out chunkBuffer, out chunkOffset, out chunkCount))
                {
                    var bytesRead = Math.Min(chunkCount, count);

                    Buffer.BlockCopy(chunkBuffer, chunkOffset, buffer, offset, bytesRead);

                    offset += bytesRead;
                    count  -= bytesRead;

                    byteSource.ReportOutput(bytesRead);
                }
            }



            if (0 != count)
            {
                long loopsWithoutProgress = 0;

                writeBuffer = buffer;
                writeOffset = offset;
                writeCount  = count;



                inconsistentState = true;

                while (0 != writeCount && !endOfFile)
                {
                    producer.Run();

                    if (madeProgress)
                    {
                        loopsWithoutProgress = 0;
                        madeProgress         = false;
                    }
                    else if (maxLoopsWithoutProgress == loopsWithoutProgress++)
                    {
                        InternalDebug.Assert(false);
                        throw new TextConvertersException(Strings.TooManyIterationsToProduceOutput);
                    }
                }

                count = writeCount;

                writeBuffer = null;
                writeOffset = 0;
                writeCount  = 0;


                inconsistentState = false;
            }

            return(initialCount - count);
        }
        /// <summary>
        /// Reads a sequence of bytes from the current stream and advances the position within the stream by the number of bytes read.
        /// </summary>
        /// <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>
        /// <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>
        /// <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>
        /// <exception cref="T:Microsoft.Exchange.Data.TextConverters.TextConvertersException">
        /// There were too many iterations without progress during conversion.
        /// </exception>
        public override int Read(byte[] buffer, int offset, int count)
        {
            if (sourceOrDestination == null)
            {
                throw new ObjectDisposedException("ConverterStream");
            }
            if (producer == null)
            {
                throw new InvalidOperationException(TextConvertersStrings.ReadUnsupported);
            }
            if (buffer == null)
            {
                throw new ArgumentNullException("buffer");
            }
            if (offset > buffer.Length || offset < 0)
            {
                throw new ArgumentOutOfRangeException("offset", TextConvertersStrings.OffsetOutOfRange);
            }
            if (count > buffer.Length || count < 0)
            {
                throw new ArgumentOutOfRangeException("count", TextConvertersStrings.CountOutOfRange);
            }
            if (count + offset > buffer.Length)
            {
                throw new ArgumentOutOfRangeException("count", TextConvertersStrings.CountTooLarge);
            }
            if (inconsistentState)
            {
                throw new InvalidOperationException(TextConvertersStrings.ConverterStreamInInconsistentStare);
            }
            int num = count;

            if (byteSource != null)
            {
                byte[] src;
                int    srcOffset;
                int    val;
                while (count != 0 && byteSource.GetOutputChunk(out src, out srcOffset, out val))
                {
                    int num2 = Math.Min(val, count);
                    Buffer.BlockCopy(src, srcOffset, buffer, offset, num2);
                    offset += num2;
                    count  -= num2;
                    byteSource.ReportOutput(num2);
                }
            }
            if (count != 0)
            {
                long num3 = 0L;
                writeBuffer       = buffer;
                writeOffset       = offset;
                writeCount        = count;
                inconsistentState = true;
                while (writeCount != 0 && !endOfFile)
                {
                    producer.Run();
                    if (madeProgress)
                    {
                        num3         = 0L;
                        madeProgress = false;
                    }
                    else
                    {
                        long arg_139_0 = maxLoopsWithoutProgress;
                        long expr_133  = num3;
                        num3 = expr_133 + 1L;
                        if (arg_139_0 == expr_133)
                        {
                            throw new TextConvertersException(TextConvertersStrings.TooManyIterationsToProduceOutput);
                        }
                    }
                }
                count             = writeCount;
                writeBuffer       = null;
                writeOffset       = 0;
                writeCount        = 0;
                inconsistentState = false;
            }
            return(num - count);
        }