         default-buffer-size get <buffer> >>buffer ; inline
 
 TUPLE: input-port < buffered-port ;
+INSTANCE: input-port noncopying-reader
 
 M: input-port stream-element-type drop +byte+ ; inline
 

    dup check-disposed
    dup wait-to-read [ drop f ] [ buffer>> buffer-pop ] if ; inline

: read-step ( count port -- byte-array/f )
    {
        { [ over 0 = ] [ 2drop f ] }
        { [ dup wait-to-read ] [ 2drop f ] }
        [ buffer>> buffer-read ]
    } cond ;

: prepare-read ( count stream -- count stream )
    dup check-disposed [ 0 max >fixnum ] dip ; inline

M: input-port stream-read-partial ( max stream -- byte-array/f )
    prepare-read read-step ;

: read-loop ( count port accum -- )
    pick over length - dup 0 > [
        pick read-step dup [
            append! read-loop
        ] [
            2drop 2drop
        ] if
    ] [
        2drop 2drop
    ] if ;

M: input-port stream-read
    prepare-read
    2dup read-step dup [
        pick over length > [
            pick <byte-vector>
            [ push-all ] keep
            [ read-loop ] keep
            B{ } like
        ] [ 2nip ] if
    ] [ 2nip ] if ;

: read-until-step ( separators port -- string/f separator/f )
    dup wait-to-read [ 2drop f f ] [ buffer>> buffer-until ] if ;

M: object underlying-handle underlying-port handle>> ;

! Fast-path optimization

HINTS: decoder-read-until { string input-port utf8 } { string input-port ascii } ;

