56 lines
1.5 KiB
C#
56 lines
1.5 KiB
C#
|
|
using System;
|
|||
|
|
using System.Collections.Generic;
|
|||
|
|
|
|||
|
|
namespace ProtoBuf.Reflection
|
|||
|
|
{
|
|||
|
|
internal sealed class Peekable<T> : IDisposable
|
|||
|
|
{
|
|||
|
|
public override string ToString()
|
|||
|
|
{
|
|||
|
|
T val;
|
|||
|
|
return Peek(out val) ? (val?.ToString() ?? "(null)") : "(EOF)";
|
|||
|
|
}
|
|||
|
|
private readonly IEnumerator<T> _iter;
|
|||
|
|
private T _peek, _prev;
|
|||
|
|
private bool _havePeek, _eof;
|
|||
|
|
public Peekable(IEnumerable<T> sequence)
|
|||
|
|
{
|
|||
|
|
_iter = sequence.GetEnumerator();
|
|||
|
|
}
|
|||
|
|
public T Previous => _prev;
|
|||
|
|
public bool Consume()
|
|||
|
|
{
|
|||
|
|
T val;
|
|||
|
|
bool haveData = _havePeek || Peek(out val);
|
|||
|
|
_prev = _peek;
|
|||
|
|
_havePeek = false;
|
|||
|
|
return haveData;
|
|||
|
|
}
|
|||
|
|
public bool Peek(out T next)
|
|||
|
|
{
|
|||
|
|
if (!_havePeek)
|
|||
|
|
{
|
|||
|
|
if (_iter.MoveNext())
|
|||
|
|
{
|
|||
|
|
_prev = _peek;
|
|||
|
|
_peek = _iter.Current;
|
|||
|
|
_havePeek = true;
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
_eof = true;
|
|||
|
|
_havePeek = false;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
if (_eof)
|
|||
|
|
{
|
|||
|
|
next = default(T);
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
next = _peek;
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
public void Dispose() => _iter?.Dispose();
|
|||
|
|
}
|
|||
|
|
}
|