Range interface for std.serialization
Dmitry Olshansky
dmitry.olsh at gmail.com
Sun Aug 25 13:50:21 PDT 2013
25-Aug-2013 23:15, Dicebot пишет:
> On Sunday, 25 August 2013 at 08:36:40 UTC, Dmitry Olshansky wrote:
>> Same thoughts here.
>> Serializer is an output range for pretty much anything (that is
>> serializable). Literally isOutputRange!T would be true for a whole lot
>> of things, making it possible to dumping any ranges of Ts via copy.
>> Just make its put method work on a variety of types and you have it.
>
> Can't it be both OutputRange itself and provide InputRange via
> `serialize` call (for filters & similar pipe processing)?
I see that you potentially want to say compress serialized data on the
fly via some range-based compressor. Or send over network... with some
byChunk(favoriteBufferSize) or rather some kind of adapter that outputs
no less then X bytes if not at end. Then indeed it becomes awkward to
model a 'sink' kind of range as it is a transformer (no matter how
convenient it makes putting stuff into it).
It looks like the serializer has 2 "ends" - one accepts any element
type, the other produces ubyte[] chunks.
A problem is how to connect that output end, or more precisely this puts
our "ranges are the pipeline" idea into an awkward situation. Basically
on the front end data may arrive in various chunks and ditto on the
output. More then that it isn't just an input range translation to
ubyte[] (at least that'd be very ineffective and restrictive). But I
have an idea.
With all that said I get to the main point hopefully. here is an example
far simpler then serialization.
No matter how we look at this there has to be a way to connect 2 sinks,
say I want to do:
//can only use output range with it
formattedWrite(compressor, "Hey, %s !\n", name);
And have said compressor use LZMA on the data that is put into it, but
it has to go somewhere. Thus problem of say compressing formatted text
is not solved by input range, nor is the filtering of said text before
'put'-ing it somewhere.
What's lacking is a way to connect a sink to another sink.
My view of it is:
auto app = appender!(ubyte[])();
//thus compression is an output range wrapper
auto compressor = compress!LZMA(app);
In other words an output range could be a filter, or rather forwarder of
the transformed result to some other output range. And we need this not
only for serialization (though formattedWrite can arguably be seen as a
serialization) but anytime we have to turn heterogeneous input into
homogeneous output and post-process THAT output.
TL;DR: Simply put - make serialization an output range, and set an
example by making archiver the first output range adapter.
Adapting the code by Jacob (Alternative AO2)
auto archiver = new XmlArchive!(char)(outputRange);
auto serializer = new Serializer(archiver);
serializer.put(new Object);
serializer.put([1, 2, 3, 4]); //mix and match stuff as you see fit
And even
copy(iota(1, 10), serializer);
Would all work just fine.
--
Dmitry Olshansky
More information about the Digitalmars-d
mailing list