Skip to content

Instantly share code, notes, and snippets.

@gsscoder
Last active November 7, 2019 14:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gsscoder/4945440 to your computer and use it in GitHub Desktop.
Save gsscoder/4945440 to your computer and use it in GitHub Desktop.
Peekable stream reader for .NET/C#
// better than PeekableStream: less code, less bugs
sealed class PeekableReader : IDisposable
{
public PeekableReader(Stream stream)
{
_stream = stream;
_byte = _stream.ReadByte();
}
public int ReadByte()
{
var current = _byte;
_byte = _stream.ReadByte();
return current;
}
public int PeekByte()
{
return _byte;
}
public char PeekChar()
{
return (char) PeekByte();
}
public string TakeWhile(Func<char, bool> predicate)
{
var builder = new StringBuilder();
while (true)
{
var raw = PeekByte();
if (raw == -1)
{
break;
}
var ch = (char)raw;
if (!predicate(ch))
{
break;
}
builder.Append(ch);
ReadByte();
}
return builder.ToString();
}
public int SkipWhile(Func<char, bool> predicate)
{
var skipped = 0;
while (true)
{
var raw = PeekByte();
if (raw == -1)
{
break;
}
var ch = (char) raw;
if (!predicate(ch))
{
break;
}
skipped++;
ReadByte();
}
return skipped;
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
private void Dispose(bool disposing)
{
if (_disposed)
{
return;
}
if (disposing)
{
if (_stream != null)
{
_stream.Dispose();
_stream = null;
}
_disposed = true;
}
}
~PeekableReader()
{
Dispose(false);
}
private int _byte;
private Stream _stream;
private bool _disposed;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment