mirror of
https://github.com/osukey/osukey.git
synced 2025-08-03 14:46:38 +09:00
Enable NRT and simplify LineBufferedReader
This commit is contained in:
@ -108,19 +108,13 @@ namespace osu.Game.Tests.Beatmaps.IO
|
||||
[Test]
|
||||
public void TestReadToEndAfterReadsAndPeeks()
|
||||
{
|
||||
const string contents = "this line is gone\rthis one shouldn't be\r\nthese ones\ndefinitely not";
|
||||
const string contents = "first line\r\nsecond line";
|
||||
|
||||
using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(contents)))
|
||||
using (var bufferedReader = new LineBufferedReader(stream))
|
||||
{
|
||||
Assert.AreEqual("this line is gone", bufferedReader.ReadLine());
|
||||
Assert.AreEqual("this one shouldn't be", bufferedReader.PeekLine());
|
||||
|
||||
string[] endingLines = bufferedReader.ReadToEnd().Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
Assert.AreEqual(3, endingLines.Length);
|
||||
Assert.AreEqual("this one shouldn't be", endingLines[0]);
|
||||
Assert.AreEqual("these ones", endingLines[1]);
|
||||
Assert.AreEqual("definitely not", endingLines[2]);
|
||||
bufferedReader.PeekLine();
|
||||
Assert.Throws<InvalidOperationException>(() => bufferedReader.ReadToEnd());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -29,7 +29,7 @@ namespace osu.Game.Beatmaps.Formats
|
||||
{
|
||||
Section section = Section.General;
|
||||
|
||||
string line;
|
||||
string? line;
|
||||
|
||||
while ((line = stream.ReadLine()) != null)
|
||||
{
|
||||
|
@ -1,10 +1,7 @@
|
||||
// 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.
|
||||
|
||||
#nullable disable
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
@ -17,58 +14,51 @@ namespace osu.Game.IO
|
||||
public class LineBufferedReader : IDisposable
|
||||
{
|
||||
private readonly StreamReader streamReader;
|
||||
private readonly Queue<string> lineBuffer;
|
||||
|
||||
private string? peekedLine;
|
||||
|
||||
public LineBufferedReader(Stream stream, bool leaveOpen = false)
|
||||
{
|
||||
streamReader = new StreamReader(stream, Encoding.UTF8, true, 1024, leaveOpen);
|
||||
lineBuffer = new Queue<string>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads the next line from the stream without consuming it.
|
||||
/// Subsequent calls to <see cref="PeekLine"/> without a <see cref="ReadLine"/> will return the same string.
|
||||
/// </summary>
|
||||
public string PeekLine()
|
||||
{
|
||||
if (lineBuffer.Count > 0)
|
||||
return lineBuffer.Peek();
|
||||
|
||||
string line = streamReader.ReadLine();
|
||||
if (line != null)
|
||||
lineBuffer.Enqueue(line);
|
||||
return line;
|
||||
}
|
||||
public string? PeekLine() => peekedLine ??= streamReader.ReadLine();
|
||||
|
||||
/// <summary>
|
||||
/// Reads the next line from the stream and consumes it.
|
||||
/// If a line was peeked, that same line will then be consumed and returned.
|
||||
/// </summary>
|
||||
public string ReadLine() => lineBuffer.Count > 0 ? lineBuffer.Dequeue() : streamReader.ReadLine();
|
||||
public string? ReadLine()
|
||||
{
|
||||
try
|
||||
{
|
||||
return peekedLine ?? streamReader.ReadLine();
|
||||
}
|
||||
finally
|
||||
{
|
||||
peekedLine = null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads the stream to its end and returns the text read.
|
||||
/// This includes any peeked but unconsumed lines.
|
||||
/// Not compatible with calls to <see cref="PeekLine"/>.
|
||||
/// </summary>
|
||||
public string ReadToEnd()
|
||||
{
|
||||
string remainingText = streamReader.ReadToEnd();
|
||||
if (lineBuffer.Count == 0)
|
||||
return remainingText;
|
||||
if (peekedLine != null)
|
||||
throw new InvalidOperationException($"Do not use {nameof(ReadToEnd)} when also peeking for lines.");
|
||||
|
||||
var builder = new StringBuilder();
|
||||
|
||||
// this might not be completely correct due to varying platform line endings
|
||||
while (lineBuffer.Count > 0)
|
||||
builder.AppendLine(lineBuffer.Dequeue());
|
||||
builder.Append(remainingText);
|
||||
|
||||
return builder.ToString();
|
||||
return streamReader.ReadToEnd();
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
streamReader?.Dispose();
|
||||
streamReader.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user