digitalmars.D.bugs - [Issue 15363] New: std.stream is depricated, which leaves missing
- via Digitalmars-d-bugs (155/155) Nov 19 2015 https://issues.dlang.org/show_bug.cgi?id=15363
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 puremagic.com Reporter: jason 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); } --
Nov 19 2015