* Change the interface of read-into to return a slice and an eof boolean separately so the compiler can optimize the slice.
* Add an each-stream-block-slice combinator that behaves like each-block but reuses a preallocated buffer for every iteration.
* Pull some strings in the stream-read-into implementation to further improve type propagation and bounds check elimination.
* with-error-stream(*)
* with-output+error-stream(*) -- sets output and error stream to same stream
* with-output>error -- sets output stream to error stream for scope
* with-input-output+error-streams(*) -- like with-streams, but sets output and error to same stream
stream-contents is extremely slow on decoder streams when implemented with each-block, and it can be implemented very quickly for streams of known length using stream-read-unsafe. Make it generic and provide some off-the-shelf implementations using each-block, a read1 loop, or length + read-unsafe. Provide new stream-seekable? and stream-length generics that can be implemented by stream implementations that know their size.
Provide default implementations of all the input-stream methods in terms of stream-read1 and of all the output-stream methods in terms of stream-write1.
Now that all streams have been updated to implement the stream-read-unsafe protocol, take out the noncopying-reader shim. Turn stream-read and stream-read-partial into plain functions over the -unsafe generics.
each-(stream-)block* is like each-block but takes a buffer object and reads into it repeatedly. (stream-)contents* determines the stream length then does a single stream-read-unsafe into a preallocated buffers. Both functions currently only work for byte-arrays (and contents* only for seekable streams), so they can't replace the non-starred versions completely just yet.
Add generics stream-read-unsafe and stream-read-partial-unsafe, which take a buffer pointer and return a count of bytes read instead of returning a freshly allocated byte array.