IO Streams
License
Boost License 1.0.
Authors
Jason White
Description:
This module provides range interfaces for streams. This is useful for using many of the range operations in std.range and std.algorithm.

There is an important distinction between streams and ranges to be made. Fundamentally, a stream is a unidirectional stream of bytes. That is, there is no going backwards and there is no saving the current position (as bidirectional and forward ranges can do). This provides a good mapping to input ranges and output ranges. As streams only operate on raw bytes, ranges provide an abstraction to operate on more complex data types.

struct  ByChunk(Stream) if (isSource!Stream);

Range that reads up to a fixed size chunk of data from a stream at a time.


this(Stream source, size_t size = 4096);

Initializes the range. A byte buffer with the given size is allocated to hold the chunks.

Parameters
Stream source A stream that can be read from.
size_t size The size of each chunk to read at a time.

this(Stream source, ubyte[] buffer);

Initializes the range with the specified buffer. This is useful for providing your own buffer that may be stack allocated.

Parameters
Stream source A stream that can be read from.
ubyte[] buffer A byte array to hold each chunk as it is read.

void  popFront();

Reads the next chunk from the stream.


const pure const(ubyte)[]  front();

Returns
The current chunk of the stream.

Note that a full chunk is not guaranteed to be returned. In the event of a partial read from the stream, this will be less than the maximum chunk size. Code should be impartial to the size of the returned chunk.

const pure nothrow bool  empty();

Returns true if there are no more chunks to be read from the stream.


auto  byChunk(Stream)(Stream stream, size_t size = 4096) if (isSource!Stream);
auto  byChunk(Stream)(Stream stream, ubyte[] buffer) if (isSource!Stream);

Convenience function for creating a ByChunk range over a stream.

Example:
import std.digest.digest : digest;
import std.digest.sha : SHA1;
import io.file;

// Hash a file, 4KiB chunks at a time
ubyte[4096] buf;
auto sha1 = digest!SHA1(File("foo").byChunk(buf));

struct  ByBlock(T, Stream) if (isSource!Stream);

Wraps a stream in a range interface such that blocks of a fixed size are read from the source. It is assumed that the stream is buffered so that performance is not adversely affected.

Since streams and ranges are fundamentally different, this is useful for performing range operations on streams.

Note:
This is an input range and cannot be saved with save(). Thus, usage of this should not be mixed with the underlying stream without first seeking to a specific location in the stream.

this(Stream source);

Initializes the range with a source stream.


void  popFront();

Removes one block from the stream.


const pure nothrow @property ref const(T)  front();

Returns
The current block in the stream.

const pure nothrow @property bool  empty();

The range is considered  empty when less than T.sizeof bytes can be read from the stream.

Returns
True if there are no more blocks in the stream and false otherwise.

@property auto  byBlock(T, Stream)(Stream stream) if (isSource!Stream);

Helper function for constructing a block range.

Example:
import std.algorithm : equal;
import std.range : take;

size_t  endsWithSeparator(T, Separator)(const(T)[] region, const Separator separator) if (is(typeof(T.init == Separator.init) : bool));
size_t  endsWithSeparator(T, Separator)(const(T)[] region, Separator sep) if (isBidirectionalRange!Separator && is(typeof(T.init == sep.back.init) : bool));

Checks if the given region ends with the given separator.

Returns
The number of elements that match.

enum auto  isSplitFunction(alias fn, T, Separator);

Checks if the given function can be used with Splitter.

Examples
static assert(isSplitFunction!(endsWithSeparator, char, char));
static assert(isSplitFunction!(endsWithSeparator, char, string));

struct  Splitter(T, Separator, Stream, alias splitFn = endsWithSeparator!(T, Separator)) if (isSource!Stream && isSplitFunction!(splitFn, T, Separator));

Splits a stream using a separator. The separator can be a single element or a bidirectional range of elements.


const pure nothrow const(T)[]  front();

Gets the current region in the stream.


const pure nothrow bool  empty();

Returns true if there are no more regions in the splitter.


auto  splitter(T = char, Separator, Stream)(Stream stream, Separator separator) if (isSource!Stream);

Convenience function for returning a stream  splitter.

Parameters
T Type of each element in the stream.
Stream stream A sink stream that can be read from.
Separator separator An element or range of elements to split on.
Example:
// Get a list of words from standard input.
import io;
import std.algorithm : map, filter;
import std.array : array;
auto words = stdin.splitter!char(' ')
                  .filter!(w => w != "")
                  .map!(w => w.idup)
                  .array;