www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - std.stdio.File lacking range-based rawWrite

reply "H. S. Teoh via Digitalmars-d" <digitalmars-d puremagic.com> writes:
Today I was writing some range-based image-generation code, which
produces a range of ubytes representing the resulting image file.  To my
astonishment, there was no function in std.stdio that could spool this
range to a File.

Initially, I tried lockingTextWriter, but quickly discovered that the
resulting file was corrupt, because it's attempting to interpret binary
data as text.

Eventually, I came upon the naive solution:

	auto f = File(...);
	ubyteRange
		.chunks(bufSize)
		.map!array
		.each!(b => f.rawWrite(b));

This is rather allocation-heavy, so here's attempt #2, that allocates a
single buffer that's reused:

	void bufferedWrite(R)(R range, ref File dest, size_t bufSize = 64*1024)
		if (isInputRange!R && is(ElementType!R : ubyte))
	{
	    import std.algorithm.iteration : each, map;
	    import std.algorithm.mutation : copy;
	    import std.range : chunks;

	    ubyte[] buf;
	    buf.length = bufSize;
	    range.chunks(bufSize)
		 .each!((chunk) {
		    auto sizeLeft = copy(chunk, buf).length;
		    dest.rawWrite(buf[0 .. $-sizeLeft]);
		 });
	}

	auto f = File(...);
	ubyteRange.bufferedWrite(f);

What do y'all think? Is bufferedWrite (potentially under a different
name) worth submitting to Phobos?


T

-- 
If creativity is stifled by rigid discipline, then it is not true creativity.
Jan 07
parent Vladimir Panteleev <thecybershadow.lists gmail.com> writes:
On Friday, 8 January 2016 at 06:27:05 UTC, H. S. Teoh wrote:
 Today I was writing some range-based image-generation code, 
 which produces a range of ubytes representing the resulting 
 image file.  To my astonishment, there was no function in 
 std.stdio that could spool this range to a File.
There's toFile... I need to wrap it up though. https://github.com/D-Programming-Language/phobos/pull/2011
Jan 07