Optimise some special cases in StreamReader; return a new Buffer from read() immediately if there's enough buffered data, and if the read can be fulfilled entirely from the first queued buffer than take a slice rather than copying into a new buffer.
Implement masking as a transform stream.