private int EnsureRawBuffer(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."); } long availableBytes; int margin; if (requestedLength <= _rawBuffer.Count || _rawBuffer.Free == 0 || (availableBytes = _innerStream.Length - _innerStream.Position) == 0L) { return(_rawBuffer.Count); } requestedLength = _rawBuffer.Free; if (availableBytes < (long)requestedLength) { requestedLength = (int)availableBytes; } byte[] buffer = new byte[_rawBuffer.Free]; requestedLength = _innerStream.Read(buffer, 0, requestedLength); if (requestedLength < 1) { return(0); } margin = _rawBuffer.Write(requestedLength, buffer); margin = (margin > 0) ? requestedLength - margin : requestedLength; if (margin > 0) { availableBytes = _innerStream.Position - (long)margin; _innerStream.Seek((availableBytes > 0L) ? availableBytes : 0L, SeekOrigin.Begin); } return(_rawBuffer.Count); } finally { Monitor.Exit(_syncRoot); } }
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); } }