// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. using System; using System.IO; using System.Text; namespace osu.Game.IO { /// /// A -like decorator (with more limited API) for s /// that allows lines to be peeked without consuming. /// public class LineBufferedReader : IDisposable { private readonly StreamReader streamReader; private string? peekedLine; public LineBufferedReader(Stream stream, bool leaveOpen = false) { streamReader = new StreamReader(stream, Encoding.UTF8, true, -1, leaveOpen); } /// /// Reads the next line from the stream without consuming it. /// Subsequent calls to without a will return the same string. /// public string? PeekLine() => peekedLine ??= streamReader.ReadLine(); /// /// Reads the next line from the stream and consumes it. /// If a line was peeked, that same line will then be consumed and returned. /// public string? ReadLine() { try { return peekedLine ?? streamReader.ReadLine(); } finally { peekedLine = null; } } /// /// Reads the stream to its end and returns the text read. /// Not compatible with calls to . /// public string ReadToEnd() { if (peekedLine != null) throw new InvalidOperationException($"Do not use {nameof(ReadToEnd)} when also peeking for lines."); return streamReader.ReadToEnd(); } public void Dispose() { streamReader.Dispose(); } } }