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();
 | |
|     }
 | |
| }
 |