[Issue 15363] New: std.stream is depricated, which leaves missing features
via Digitalmars-d-bugs
digitalmars-d-bugs at puremagic.com
Thu Nov 19 02:41:40 PST 2015
https://issues.dlang.org/show_bug.cgi?id=15363
Issue ID: 15363
Summary: std.stream is depricated, which leaves missing
features
Product: D
Version: D2
Hardware: All
OS: All
Status: NEW
Severity: enhancement
Priority: P1
Component: phobos
Assignee: nobody at puremagic.com
Reporter: jason at spashett.com
Since std.stream is to be removed, there will be some missing features that
really should be part of the language, in my opinion. It probably would have
been better to implement the replacement functinality before deprecating
std.stream.
The following two things I have ran into (so far):
There is no longer a 'stream' concept. Instead one has to say
File.byChunk(x).joiner on File objects.
It's important to have an abstract notion of a stream type thing for working
on:
files
memory
sockets
...etc
i.e. the need to pass said abstract thing into a function, that can then
perform the needed operation, weather it be from a file, memory, socket...
This, undoubtedly should be a range in D, but getting one by using
.byChunk(x).joiner on the File object is not very obvious at all. (See example
code for stream demonstration) This sort of range type should be made available
on all things that can have stream like facilities, and it should be an
InputRange, so as the result can be used with a wide variety of algorithms.
The lineSplitter algorithm does not work unless the range it's given has
slicing and length. This is a drawback if you want to use it with a "steam."
i.e. it's useless.
A different lineSplitter is required I think (see example code). This will have
to allocate a line buffer though.
----- example implementation --------
module missing;
import std.algorithm;
import std.stdio;
/* test.txt
the quick brown fox
jumped over
the lazy dogs.
*/
unittest {
/*
* A file Stream.
* This is similar to File.byChunk(n).join() but a bit less odd
*/
{
std.stdio.File f = std.stdio.File("test.txt");
assert(f.isOpen());
//auto s = f.byChunk(4).joiner;
auto s = f.stream(4);
assert(!s.empty);
foreach (char c; s) {
writef("%c", c);
}
}
/*
* Line split without reading the whole file.
*/
{
std.stdio.File f = std.stdio.File("test.txt");
assert(f.isOpen());
auto s = f.stream(4);
assert(!s.empty);
auto lines = lineSpliterCopy(s);
foreach (char[] line; lines) {
writefln("Line: %s", line);
}
}
import std.c.stdlib;
exit(1);
}
/*
** Return range of chars
*/
auto stream(std.stdio.File f, size_t bufferSize = 4096)
{
struct Stream
{
this(std.stdio.File f, size_t bufferSize)
{
file = f;
buffer = new char[bufferSize];
fill();
}
void popFront()
{
slice = slice[1..$];
if (empty)
fill();
}
char front()
{
return slice[0];
}
@property
bool empty() const {
return slice.length == 0;
}
private:
void fill()
{
slice = file.rawRead(buffer);
}
char[] buffer, slice;
std.stdio.File file;
}
return Stream(f, bufferSize);
}
/*
** A inputRange range that returns lines. Allocating a single line
*/
auto lineSpliterCopy(Range)(Range range)
{
struct Splitter
{
this(Range range)
{
this.source = range;
popFront();
}
void popFront()
{
line = null;
while (!source.empty() ) {
char c = source.front();
if (c == '\n') {
source.popFront();
break;
}
line ~= c;
source.popFront();
}
}
char[] front()
{
return line;
}
bool empty() {
return line is null;
}
private:
Range source;
char[] line;
}
return Splitter(range);
}
--
More information about the Digitalmars-d-bugs
mailing list