OutputRanges and slicing/save()

Justin Whear justin at economicmodeling.com
Fri Jan 3 14:56:41 PST 2014


I've run into a design issue surrounding ranges and am looking for advice 
on the best way to proceed.  To illustrate the issue, consider the 
Shapefile format: a 100 byte header followed by variable-length records.  
The tricky bit is that the header includes a field which contains the 
total length of the file (as measured in 16-bit words, curiously).  The 
header must be written first, but the total length of the file isn't 
known until all the records have been encoded.  When writing to a File 
this isn't a problem: write 100 bytes of padding, write the records, use 
rewind(), and write the proper header.  It's in the context of an 
OutputRange that I don't know how to proceed.  Consider the most flexible 
range type: the array.  An array is not an OutputRange, so it needs to be 
wrapped in something like std.array.Appender.  Ideally I could save off 
the initial state of the range, write a bogus header, write the records, 
then jump back and write the proper header.  Unfortunately, Appender is 
not a ForwardRange, nor does it appear that the field of OutputRanges 
which are also ForwardRanges has been explored.  I'm using the excellent 
read, write, and append functions from std.bitmanip, so write() would fit 
the bill if only Appender supported slicing.

My current solution is require the user to construct the ShapeWriter 
output range (which supports `put(Shape)`) over two separate output 
ranges of ubyte: one for the header and a second for the records, then 
delay writing to the header range until the record range is complete.  
This is both needlessly complex and it leaves the proper combination of 
the two to the user, making ShapeWriter a very leaky abstraction.

So, for particular questions:
1) Am I missing something in Phobos that would provide an OutputRange of 
ubytes while also providing ForwardRange/slicing capabilities?
2) I know the relationship between streams and ranges has been discussed 
at least once before; is the concept of rewinding and overwriting simply 
incompatible with OutputRange in general?

Justin


More information about the Digitalmars-d mailing list