2019-09-09 21:41:51 +00:00
|
|
|
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. 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
|
|
|
|
|
{
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// A <see cref="StreamReader"/>-like decorator (with more limited API) for <see cref="Stream"/>s
|
|
|
|
|
/// that allows lines to be peeked without consuming.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public class LineBufferedReader : IDisposable
|
|
|
|
|
{
|
|
|
|
|
private readonly StreamReader streamReader;
|
2022-07-06 05:29:55 +00:00
|
|
|
|
|
|
|
|
|
private string? peekedLine;
|
2019-09-09 21:41:51 +00:00
|
|
|
|
|
2020-03-31 01:13:50 +00:00
|
|
|
|
public LineBufferedReader(Stream stream, bool leaveOpen = false)
|
2019-09-09 21:41:51 +00:00
|
|
|
|
{
|
2022-07-08 21:01:22 +00:00
|
|
|
|
streamReader = new StreamReader(stream, Encoding.UTF8, true, 1024, leaveOpen);
|
2019-09-09 21:41:51 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Reads the next line from the stream without consuming it.
|
2019-09-10 20:06:10 +00:00
|
|
|
|
/// Subsequent calls to <see cref="PeekLine"/> without a <see cref="ReadLine"/> will return the same string.
|
2019-09-09 21:41:51 +00:00
|
|
|
|
/// </summary>
|
2022-07-06 05:29:55 +00:00
|
|
|
|
public string? PeekLine() => peekedLine ??= streamReader.ReadLine();
|
2019-09-09 21:41:51 +00:00
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Reads the next line from the stream and consumes it.
|
2019-09-10 20:06:10 +00:00
|
|
|
|
/// If a line was peeked, that same line will then be consumed and returned.
|
2019-09-09 21:41:51 +00:00
|
|
|
|
/// </summary>
|
2022-07-06 05:29:55 +00:00
|
|
|
|
public string? ReadLine()
|
|
|
|
|
{
|
2022-07-06 10:55:43 +00:00
|
|
|
|
string? line = peekedLine ?? streamReader.ReadLine();
|
|
|
|
|
|
|
|
|
|
peekedLine = null;
|
|
|
|
|
return line;
|
2022-07-06 05:29:55 +00:00
|
|
|
|
}
|
2019-09-09 21:41:51 +00:00
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Reads the stream to its end and returns the text read.
|
2022-07-06 10:53:19 +00:00
|
|
|
|
/// This includes any peeked but unconsumed lines.
|
2019-09-09 21:41:51 +00:00
|
|
|
|
/// </summary>
|
|
|
|
|
public string ReadToEnd()
|
|
|
|
|
{
|
2022-07-06 10:53:19 +00:00
|
|
|
|
string remainingText = streamReader.ReadToEnd();
|
|
|
|
|
if (peekedLine == null)
|
|
|
|
|
return remainingText;
|
2019-09-09 21:41:51 +00:00
|
|
|
|
|
2022-07-06 10:53:19 +00:00
|
|
|
|
var builder = new StringBuilder();
|
|
|
|
|
|
|
|
|
|
// this might not be completely correct due to varying platform line endings
|
|
|
|
|
builder.AppendLine(peekedLine);
|
|
|
|
|
builder.Append(remainingText);
|
|
|
|
|
|
|
|
|
|
return builder.ToString();
|
2019-09-09 21:41:51 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void Dispose()
|
|
|
|
|
{
|
2022-07-06 05:29:55 +00:00
|
|
|
|
streamReader.Dispose();
|
2019-09-09 21:41:51 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|