Пример #1
0
        private int EnsureCharBuffer(int requestedLength)
        {
            Monitor.Enter(_syncRoot);
            try
            {
                if (_lineIndex < -1)
                {
                    throw new ObjectDisposedException(GetType().AssemblyQualifiedName);
                }

                if (_lineIndex < 0)
                {
                    throw new InvalidOperationException("Stream reader has already been closed.");
                }

                int availableSpace;
                int bytesInRequestedChars = _encoding.GetMaxByteCount(requestedLength);
                if (requestedLength <= _charBuffer.Count || _charBuffer.Free == 0 || (availableSpace = EnsureRawBuffer(bytesInRequestedChars)) == 0)
                {
                    return(_charBuffer.Count);
                }

                requestedLength = _charBuffer.Free;
                char[] convertedChars;
                try { convertedChars = _encoding.GetChars(_rawBuffer.Peek(bytesInRequestedChars)); }
                catch { convertedChars = _encoding.GetChars(_rawBuffer.Peek(bytesInRequestedChars - 1)); }
                int charAddCount = _charBuffer.Write(convertedChars);
                if (charAddCount < requestedLength)
                {
                    convertedChars = convertedChars.Take(charAddCount).ToArray();
                }
                _rawBuffer.Purge(_encoding.GetByteCount(convertedChars));
                return(_charBuffer.Count);
            }
            finally { Monitor.Exit(_syncRoot); }
        }
Пример #2
0
        public override int Peek()
        {
            Monitor.Enter(_syncRoot);
            try
            {
                if (_lineIndex < -1)
                {
                    throw new ObjectDisposedException(GetType().AssemblyQualifiedName);
                }

                if (_lineIndex < 0)
                {
                    throw new InvalidOperationException("Stream reader has already been closed.");
                }

                EnsureCharBuffer(1);
                return(_charBuffer.Peek(1).Cast <int>().DefaultIfEmpty(-1).First());
            }
            finally { Monitor.Exit(_syncRoot); }
        }
Пример #3
0
        public RewindableStreamReader(Stream stream, Encoding encoding, bool detectEncodingFromByteOrderMarks, int bufferSize, bool leaveOpen,
                                      bool omitCrFromNewLine)
        {
            if (stream == null)
            {
                throw new ArgumentNullException("stream");
            }

            if (!stream.CanRead)
            {
                throw new ArgumentException("The stream does not support reading.", "stream");
            }

            if (!stream.CanSeek)
            {
                throw new ArgumentException("The stream does not support seeking.", "stream");
            }

            if (bufferSize < 1)
            {
                throw new ArgumentOutOfRangeException("bufferSize", "Buffer size must be greater than zero.");
            }

            _leaveOpen  = leaveOpen;
            _rawBuffer  = new ValueBuffer <byte>(bufferSize);
            _charBuffer = new ValueBuffer <char>(bufferSize);

            if (detectEncodingFromByteOrderMarks)
            {
                int readLen;
                try
                {
                    ReadOnlyCollection <Tuple <Encoding, byte[]> > detectableEncodings = DetectableEncodings;
                    readLen = DetectableEncodings[0].Item2.Length;
                    EnsureRawBuffer(readLen);
                }
                catch (ObjectDisposedException exception)
                {
                    throw new InvalidOperationException("Stream has already been disposed", exception);
                }
                if (_rawBuffer.Count >= DetectableEncodings[DetectableEncodings.Count - 1].Item2.Length)
                {
                    byte[]   bom = _rawBuffer.Peek(readLen);
                    Encoding e   = (bom.Length > 0) ? DetectEncodingFromBytes(bom, 0, bom.Length) : null;
                    if (e != null)
                    {
                        bom = e.GetPreamble();
                        if (bom.Length > 0 && _rawBuffer.StartsWith(bom))
                        {
                            _rawBuffer.Purge(bom.Length);
                        }
                        encoding = e;
                    }
                }
            }

            if (encoding == null)
            {
                encoding = DefaultEncoding;
            }
            _encoding = encoding.Clone() as Encoding;
            _encoding.DecoderFallback = new DecoderExceptionFallback();
            _encoding.EncoderFallback = new EncoderExceptionFallback();
            _maxSingleCharByteCount   = (_encoding.IsSingleByte) ? 1 : _encoding.GetMaxByteCount(1);
            _omitCrFromNewLine        = omitCrFromNewLine;
            _newLineCharSequence      = (omitCrFromNewLine) ? new char[] { '\n' } : new char[] { '\r', '\n' };
            _newLineByteSequence      = _encoding.GetBytes(_newLineCharSequence);
            _innerStream = stream;
        }