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); } }
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; }