 M: object underlying-handle underlying-port handle>> ;
 
 ! Fast-path optimization
-USING: hints strings io.encodings.utf8 io.encodings.ascii
-io.encodings.private ;
 
 HINTS: decoder-read-until { string input-port utf8 } { string input-port ascii } ;
 

! Copyright (C) 2005, 2010 Slava Pestov, Doug Coleman
! See http://factorcode.org/license.txt for BSD license.
USING: math kernel io sequences io.buffers io.timeouts generic
byte-vectors system io.encodings math.order io.backend
continuations classes byte-arrays namespaces splitting grouping
dlists alien alien.c-types alien.data assocs io.encodings.binary
summary accessors destructors combinators fry specialized-arrays
locals ;
SPECIALIZED-ARRAY: uchar
IN: io.ports

SYMBOL: default-buffer-size

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

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

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

M: input-port stream-read-partial-unsafe ( n dst port -- count )
    [ swap ] dip prepare-read read-step
    [ swap [ memcpy ] keep ] [ 2drop 0 ] if* ;

:: read-loop ( n-remaining n-read port dst -- n-total )
    n-remaining 0 > [
        n-remaining port read-step :> ( n-buffered ptr )
        ptr [
            dst ptr n-buffered memcpy
            n-remaining n-buffered - :> n-remaining'
            n-read n-buffered + :> n-read'
            n-buffered dst <displaced-alien> :> dst'
            n-remaining' n-read' port dst' read-loop
        ] [ n-read ] if
    ] [ n-read ] if ; inline recursive

M:: input-port stream-read-unsafe ( n dst port -- count )
    n port prepare-read :> ( n' port' )
    n' port' read-step :> ( n-buffered ptr )
    ptr [
        dst ptr n-buffered memcpy
        n-buffered n' < [
            n-buffered dst <displaced-alien> :> dst'
            n' n-buffered - n-buffered port dst' read-loop
        ] [
            n-buffered
        ] if
    ] [ 0 ] if ;

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