Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- struct RefEnumerable
- {
- readonly Stream stream;
- public RefEnumerable(Stream stream)
- {
- this.stream = stream;
- }
- public Enumerator GetEnumerator() => new Enumerator(this);
- public ref struct Enumerator
- {
- static readonly int ItemSize = Unsafe.SizeOf<Foo>();
- readonly Stream stream;
- readonly Span<Foo> buffer;
- readonly Span<byte> rawBuffer;
- bool lastBuffer;
- long loadedItems;
- int currentItem;
- public Enumerator(RefEnumerable enumerable)
- {
- stream = enumerable.stream;
- buffer = new Foo[100]; // alloc items buffer
- rawBuffer = buffer.NonPortableCast<Foo, byte>(); // cast items buffer to bytes buffer (no copies)
- lastBuffer = false;
- loadedItems = 0;
- currentItem = -1;
- }
- public ref readonly Foo Current => ref buffer[currentItem];
- public bool MoveNext()
- {
- if (++currentItem != loadedItems) // increment current position and check if reached end of buffer
- return true;
- if (lastBuffer) // check if it was the last buffer
- return false;
- // get next buffer
- var bytesRead = stream.Read(rawBuffer);
- lastBuffer = bytesRead < rawBuffer.Length;
- currentItem = 0;
- loadedItems = bytesRead / ItemSize;
- return loadedItems != 0;
- }
- }
- }
Add Comment
Please, Sign In to add comment