Analogous to read-unsafe/read-into for streams (and thereby TCP sockets), provide receive-unsafe and receive-into words for datagram sockets that receive into a caller-supplied buffer.
Implement M: utf16[bl]e encode-string to use a fast implementation if a string is ASCII only, and do some inlining so the slow path optimizes a bit better.
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.
Now that "io" provides a method on object for stream-read-partial-unsafe that forwards to stream-read-unsafe, individual stream class that don't implement partial reads don't need to provide such a method themselves.
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.
Some binary stream types use memcpy to implement read-unsafe, while element-agnostic wrapper streams have to use copy. Make sure peek-stream works with both when it has to divide a read between the peek buffer and the underlying buffer (it does).
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.
†there's a failing test with this patch that needs investigation:
===
resource:basis/ui/tools/listener/listener-tests.factor: 90
Unit Test: { [ t ] [ "promise" get 2 seconds ?promise-timeout text = ] }
wait-timeout
===
stream-contents is apparently way slow for decoders. Write decode out more directly as a read1/push loop so it's faster. encode isn't quite as bad, but we can still get a 25% speed improvement by writing to an appropriately sized byte-vector.
Add guess-encoded-length and guess-decoded-length generics that encodings can implement to provide hints as to how large the translation product will be, for sizing vectors and things like that.
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.