Skip to content

Instantly share code, notes, and snippets.

@electricessence
Last active August 21, 2021 22:50
Show Gist options
  • Save electricessence/3b4b2bbc6e6a767d5c437f6605358835 to your computer and use it in GitHub Desktop.
Save electricessence/3b4b2bbc6e6a767d5c437f6605358835 to your computer and use it in GitHub Desktop.
Text Reader Extensions
using System;
using System.Buffers;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
public static class TextReaderExtensions
{
public static async IAsyncEnumerable<ReadOnlyMemory<char>> SingleBufferReadAsync(
this TextReader reader,
int bufferSize = 4096)
{
var pool = MemoryPool<char>.Shared;
using var A = pool.Rent(bufferSize);
var buffer = A.Memory;
while (true)
{
var n = await reader.ReadAsync(buffer).ConfigureAwait(false);
if (n == 0) break;
yield return n == buffer.Length ? buffer : buffer.Slice(0, n);
}
}
public static async IAsyncEnumerable<ReadOnlyMemory<char>> DualBufferReadAsync(
this TextReader reader,
int bufferSize = 4096)
{
var pool = MemoryPool<char>.Shared;
using var A = pool.Rent(bufferSize);
using var B = pool.Rent(bufferSize);
var cNext = A.Memory;
var cCurrent = B.Memory;
var next = reader.ReadAsync(cNext);
while (true)
{
var n = await next.ConfigureAwait(false);
if (n == 0) break;
// Preemptive request before yielding.
var current = reader.ReadAsync(cCurrent);
yield return n == cNext.Length ? cNext : cNext.Slice(0, n);
var swap = cNext;
cNext = cCurrent;
cCurrent = swap;
next = current;
}
}
public static async IAsyncEnumerable<string> PreemptiveReadLineAsync(
this TextReader reader)
{
var next = reader.ReadLineAsync();
while (true)
{
var n = await next.ConfigureAwait(false);
if (n == null) break;
// Preemptive request before yielding.
next = reader.ReadLineAsync();
yield return n;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment