Right now we have a concept of generic streams represented by the
types "svn_read_fn_t" and "svn_write_fn_t". We might add an
"svn_seekread_fn_t" in order to do seekable delta application, and
could conceivably want generic streams that you can seek and write to
as well, someday. When you want to pass a generic stream to a
function, you give it an svn_read_fn_t and a baton (a void *).
I've been thinking about a two different variations on this idea which
might or might not make the world of generic streams a happier place:
Variation 1: We create types svn_input_stream_t and
svn_output_stream_t, and later svn_seekinput_stream_t. These
types are built out of svn_read_fn_t's and their batons. (And
maybe pools. I'm not sure.)
The advantage here is that functions which use generic streams
need fewer arguments, lending greater clarity to their
interfaces. The disadvantage is that you have to actually
construct these guys.
Variation 2: We create a single type svn_stream_t, which
contains a baton and functions for reading, writing, and
someday seek-reading and maybe seek-writing. Some of the
functions might be NULL.
The advantage over variation 1 is that there are fewer types
running around in the system (and it has a shorter name), it
becomes possible to represent bidirectional streams, and
certain kinds of polymorphism become possible. (For instance,
we could have a single interface for applying an svndiff,
regardless of whether we're doing seekable application or not,
and regardless of whether we want to operate in "push" or
"pull" mode.) And you can represent bidirectional generic
streams as a single object. The disadvantage is that we get
less type-safety; if you pass a non-readable stream to a
function which wants an input stream, you won't find out until
runtime.
All of this is, of course, totally orthogonal to putting generic
streams into aprutil.
Opinions? I could go either way, on both variations.
Received on Sat Oct 21 14:36:16 2006