 GENERIC: stream-read-until ( seps stream -- seq sep/f )
 GENERIC: stream-read-partial-unsafe ( n buf stream -- count )
 GENERIC: stream-readln ( stream -- str/f )
+GENERIC: stream-contents ( stream -- seq )
 
 GENERIC: stream-write1 ( elt stream -- )
 GENERIC: stream-write ( data stream -- )

: each-block ( ... quot: ( ... block -- ... ) -- ... )
    input-stream get swap each-stream-block ; inline

: stream-contents ( stream -- seq )
    [
        [ [ ] collector [ each-stream-block ] dip { } like ]
        [ stream-exemplar concat-as ] bi
    ] with-disposal ;

: stream-contents-length ( stream -- n )
    [ stream-tell ]
    [ [ 0 seek-end ] dip [ stream-seek ] [ stream-tell ] bi ]
    [ [ swap seek-absolute ] dip stream-seek ] tri ;

: stream-contents* ( stream -- seq )
    [ stream-contents-length dup (byte-array) ]
    [ [ stream-read-unsafe drop ] curry keep ] bi ;

: contents ( -- seq )
    input-stream get stream-contents ; inline

: contents* ( -- seq )
    input-stream get stream-contents* ; inline

: stream-copy* ( in out -- )
    [ stream-write ] curry each-stream-block ; inline


GENERIC: stream-tell ( stream -- n )
GENERIC: stream-seek ( n seek-type stream -- )
GENERIC: stream-seekable? ( stream -- ? )
GENERIC: stream-length ( stream -- n/f )

: stream-print ( str stream -- ) [ stream-write ] [ stream-nl ] bi ;

