On Wednesday, 17 February 2016 at 10:54:56 UTC, John Colvin wrote:
Why not just say it's a ubyte and then compose with ranges from
there?
You could put a range interface on it... but I think it would be
of very limited value. For one, what about fseek? How does that
interact with the range interface?
Or, what about reading a network interface where you get
variable-sized packets?
A ubyte[] is probably the closest thing you can get to
usefulness, but even then you'd need non-range buffering controls
to make it efficient and usable. Consider the following:
Packet 1: 11\nHello
Packet 2: World05\nD ro
Packet 3: x
You take the ubyte[] thing that gives each packet at a time as it
comes off the hardware interface. Good, you can process as it
comes and it fits the range interface.
But it isn't terribly useful. Are you going to copy the partial
message into another buffer so the next range.popFront doesn't
overwrite it? Or will you present the incomplete message from
packet 1 to the consumer? The former is less than efficient (and
still needs to wrap the range in some other interface to make the
user code pretty) and the latter leads to ugly user code being
directly exposed.
Copying it into a buffer is probably the most sane... but it is a
wasteful copy if your existing buffer has enough space. But how
to you say that to a range? popFront takes no arguments.
What about packet 2, which has part of the first message and part
of the second message? Can you tell it that you already consumed
the first six bytes and it can now append the next packet to the
existing buffer, but please return that slice on the next call?
Ranges are great for a sequence of data that is the same type on
each call. Files, however, tend to have variable length (which
you might want to skip large sections of) and different types of
data as you iterate through them.
I find std.stdio's byChunk and byLine to be almost completely
useless in my cases.