/// <summary> /// Helper method to try to read next character from bound <see cref="PotentiallyAsyncReader{TValue}"/>, or throw if no more characters can be read. /// </summary> /// <typeparam name="TValue">The type of values that this reader produces.</typeparam> /// <param name="reader">This <see cref="PotentiallyAsyncReader{TValue}"/>.</param> /// <returns>A task which will return character read.</returns> /// <exception cref="NullReferenceException">If this <see cref="PotentiallyAsyncReader{TValue}"/> is <c>null</c>.</exception> /// <exception cref="EndOfStreamException">If no more characters could be read from the source.</exception> public static async ValueTask <TValue> ReadNextAsync <TValue>( this PotentiallyAsyncReader <TValue?> reader ) where TValue : struct { return(await ArgumentValidator.ValidateNotNullReference(reader).TryReadNextAsync() ?? throw new EndOfStreamException()); }
/// <summary> /// Helper method to try to read next value from this <see cref="PotentiallyAsyncReader{TValue}"/>, or throw if no more values can be read. /// </summary> /// <typeparam name="TValue">The type of values that this reader produces.</typeparam> /// <param name="reader">This <see cref="PotentiallyAsyncReader{TValue}"/>.</param> /// <param name="checker">Optional callback to check value. If it is supplied, this method will keep reading values until this callback returns <c>true</c>.</param> /// <returns>A task which will return last value read.</returns> /// <exception cref="NullReferenceException">If this <see cref="PotentiallyAsyncReader{TValue}"/> is <c>null</c>.</exception> /// <exception cref="EndOfStreamException">If no more values could be read from the source.</exception> public static async ValueTask <TValue> ReadUntilAsync <TValue>( this PotentiallyAsyncReader <TValue?> reader, Func <TValue, Boolean> checker ) where TValue : struct { return(await reader.TryReadUntilAsync(checker) ?? throw new EndOfStreamException()); }
/// <summary> /// Helper method to try to read next value from this <see cref="PotentiallyAsyncReader{TValue}"/> until suitable value has been read, or values will end. /// </summary> /// <typeparam name="TValue">The type of values that this reader produces.</typeparam> /// <param name="reader">This <see cref="PotentiallyAsyncReader{TValue}"/>.</param> /// <param name="checker">Optional callback to check value. If it is supplied, this method will keep reading values until this callback returns <c>true</c>.</param> /// <returns>A task which will return last value read.</returns> /// <exception cref="NullReferenceException">If this <see cref="PotentiallyAsyncReader{TValue}"/> is <c>null</c>.</exception> public static async ValueTask <TValue?> TryReadUntilAsync <TValue>( this PotentiallyAsyncReader <TValue?> reader, Func <TValue, Boolean> checker ) where TValue : struct { ArgumentValidator.ValidateNotNullReference(reader); TValue?charRead; do { charRead = await reader.TryReadNextAsync(); } while (charRead.HasValue && !(checker?.Invoke(charRead.Value) ?? true)); return(charRead); }
/// <summary> /// This helper method will make this <see cref="PotentiallyAsyncReader{TValue}"/> clear the underlying buffer of <see cref="StreamReaderWithResizableBuffer"/> becomes greater or equal to than given limit, until the <see cref="IDisposable.Dispose"/> method is called. /// </summary> /// <param name="reader">This <see cref="PotentiallyAsyncReader{TValue}"/>.</param> /// <param name="source">The <see cref="StreamReaderWithResizableBuffer"/> to clear after each character read.</param> /// <param name="maxCount">The maximum amount of bytes that can be seen in <paramref name="source"/>.</param> /// <returns>The <see cref="IDisposable"/> to specify a segment of code which will cause underlying stream buffer to empty after each character read.</returns> /// <exception cref="NullReferenceException">If this <see cref="PotentiallyAsyncReader{TValue}"/> is <c>null</c>.</exception> public static IDisposable ClearStreamWhenStreamBufferTooBig <TValue>( this PotentiallyAsyncReader <TValue> reader, StreamReaderWithResizableBuffer source, Int32 maxCount ) { GenericEventHandler <ReadCompletedEventArgs <TValue> > evtHandler = args => { if (source.ReadBytesCount >= maxCount) { source.EraseReadBytesFromBuffer(); } }; ArgumentValidator.ValidateNotNullReference(reader).ReadCompleted += evtHandler; return(new UsingHelper(() => { reader.ReadCompleted -= evtHandler; source.EraseReadBytesFromBuffer(); })); }