2008-01-31 01:52:06 -05:00
|
|
|
! Copyright (C) 2005, 2008 Slava Pestov, Doug Coleman
|
2007-09-20 18:09:08 -04:00
|
|
|
! See http://factorcode.org/license.txt for BSD license.
|
|
|
|
IN: io.nonblocking
|
2008-02-09 22:34:42 -05:00
|
|
|
USING: math kernel io sequences io.buffers io.timeouts generic
|
2008-03-06 16:58:05 -05:00
|
|
|
byte-vectors system io.streams.duplex io.encodings
|
2008-02-09 22:34:42 -05:00
|
|
|
io.backend continuations debugger classes byte-arrays namespaces
|
2008-04-11 15:38:25 -04:00
|
|
|
splitting dlists assocs io.encodings.binary accessors ;
|
2007-09-20 18:09:08 -04:00
|
|
|
|
2007-11-07 14:01:45 -05:00
|
|
|
SYMBOL: default-buffer-size
|
|
|
|
64 1024 * default-buffer-size set-global
|
2007-09-20 18:09:08 -04:00
|
|
|
|
|
|
|
! Common delegate of native stream readers and writers
|
2008-01-31 01:52:06 -05:00
|
|
|
TUPLE: port
|
|
|
|
handle
|
2008-04-11 15:09:09 -04:00
|
|
|
buffer
|
2008-01-31 01:52:06 -05:00
|
|
|
error
|
2008-02-21 20:12:55 -05:00
|
|
|
timeout
|
2008-04-11 15:09:09 -04:00
|
|
|
type eof ;
|
2007-09-20 18:09:08 -04:00
|
|
|
|
2008-02-21 20:12:55 -05:00
|
|
|
M: port timeout port-timeout ;
|
|
|
|
|
|
|
|
M: port set-timeout set-port-timeout ;
|
2008-02-09 22:34:42 -05:00
|
|
|
|
2007-09-20 18:09:08 -04:00
|
|
|
SYMBOL: closed
|
|
|
|
|
2008-03-26 19:23:19 -04:00
|
|
|
PREDICATE: input-port < port port-type input-port eq? ;
|
|
|
|
PREDICATE: output-port < port port-type output-port eq? ;
|
2007-09-20 18:09:08 -04:00
|
|
|
|
|
|
|
GENERIC: init-handle ( handle -- )
|
2007-11-07 14:01:45 -05:00
|
|
|
GENERIC: close-handle ( handle -- )
|
2007-09-20 18:09:08 -04:00
|
|
|
|
2008-04-11 15:09:09 -04:00
|
|
|
: <port> ( handle type -- port )
|
|
|
|
port construct-empty
|
|
|
|
swap >>type
|
|
|
|
swap dup init-handle >>handle ;
|
2007-09-20 18:09:08 -04:00
|
|
|
|
2008-01-21 15:33:43 -05:00
|
|
|
: <buffered-port> ( handle type -- port )
|
2008-04-11 15:09:09 -04:00
|
|
|
<port>
|
|
|
|
default-buffer-size get <buffer> >>buffer ;
|
2007-09-20 18:09:08 -04:00
|
|
|
|
2008-02-22 21:21:23 -05:00
|
|
|
: <reader> ( handle -- input-port )
|
2008-02-16 16:35:44 -05:00
|
|
|
input-port <buffered-port> ;
|
2007-09-20 18:09:08 -04:00
|
|
|
|
2008-02-22 21:21:23 -05:00
|
|
|
: <writer> ( handle -- output-port )
|
2008-02-16 16:35:44 -05:00
|
|
|
output-port <buffered-port> ;
|
2007-09-20 18:09:08 -04:00
|
|
|
|
2008-02-24 02:37:05 -05:00
|
|
|
: <reader&writer> ( read-handle write-handle -- input-port output-port )
|
2008-02-24 20:58:34 -05:00
|
|
|
swap <reader> [ swap <writer> ] [ ] [ dispose drop ] cleanup ;
|
2007-09-20 18:09:08 -04:00
|
|
|
|
|
|
|
: pending-error ( port -- )
|
2008-04-11 15:09:09 -04:00
|
|
|
[ f ] change-error drop [ throw ] when* ;
|
2007-09-20 18:09:08 -04:00
|
|
|
|
2008-02-01 16:00:02 -05:00
|
|
|
HOOK: cancel-io io-backend ( port -- )
|
2008-01-31 01:52:06 -05:00
|
|
|
|
2008-02-01 16:00:02 -05:00
|
|
|
M: object cancel-io drop ;
|
2008-01-31 01:52:06 -05:00
|
|
|
|
2008-02-09 22:34:42 -05:00
|
|
|
M: port timed-out cancel-io ;
|
2007-09-20 18:09:08 -04:00
|
|
|
|
|
|
|
GENERIC: (wait-to-read) ( port -- )
|
|
|
|
|
|
|
|
: wait-to-read ( count port -- )
|
2008-04-11 15:09:09 -04:00
|
|
|
tuck buffer>> buffer-length > [ (wait-to-read) ] [ drop ] if ;
|
2007-09-20 18:09:08 -04:00
|
|
|
|
|
|
|
: wait-to-read1 ( port -- )
|
|
|
|
1 swap wait-to-read ;
|
|
|
|
|
|
|
|
: unless-eof ( port quot -- value )
|
2008-04-11 15:09:09 -04:00
|
|
|
>r dup buffer>> buffer-empty? over eof>> and
|
|
|
|
[ f >>eof drop f ] r> if ; inline
|
2007-09-20 18:09:08 -04:00
|
|
|
|
|
|
|
M: input-port stream-read1
|
2008-04-11 15:09:09 -04:00
|
|
|
dup wait-to-read1 [ buffer>> buffer-pop ] unless-eof ;
|
2007-09-20 18:09:08 -04:00
|
|
|
|
2008-03-06 16:58:05 -05:00
|
|
|
: read-step ( count port -- byte-array/f )
|
2007-09-20 18:09:08 -04:00
|
|
|
[ wait-to-read ] 2keep
|
2008-04-11 15:09:09 -04:00
|
|
|
[ dupd buffer>> buffer-read ] unless-eof nip ;
|
2007-09-20 18:09:08 -04:00
|
|
|
|
2008-03-08 03:51:26 -05:00
|
|
|
: read-loop ( count port accum -- )
|
2007-09-20 18:09:08 -04:00
|
|
|
pick over length - dup 0 > [
|
|
|
|
pick read-step dup [
|
|
|
|
over push-all read-loop
|
|
|
|
] [
|
|
|
|
2drop 2drop
|
|
|
|
] if
|
|
|
|
] [
|
|
|
|
2drop 2drop
|
|
|
|
] if ;
|
|
|
|
|
|
|
|
M: input-port stream-read
|
|
|
|
>r 0 max >fixnum r>
|
|
|
|
2dup read-step dup [
|
|
|
|
pick over length > [
|
2008-03-06 16:58:05 -05:00
|
|
|
pick <byte-vector>
|
2007-09-20 18:09:08 -04:00
|
|
|
[ push-all ] keep
|
|
|
|
[ read-loop ] keep
|
2008-03-06 16:58:05 -05:00
|
|
|
B{ } like
|
2008-04-11 15:09:09 -04:00
|
|
|
] [ 2nip ] if
|
|
|
|
] [ 2nip ] if ;
|
2007-09-20 18:09:08 -04:00
|
|
|
|
2008-03-06 16:58:05 -05:00
|
|
|
M: input-port stream-read-partial ( max stream -- byte-array/f )
|
2007-09-20 18:09:08 -04:00
|
|
|
>r 0 max >fixnum r> read-step ;
|
|
|
|
|
2008-04-11 15:09:09 -04:00
|
|
|
: can-write? ( len buffer -- ? )
|
2007-11-09 03:01:45 -05:00
|
|
|
[ buffer-fill + ] keep buffer-capacity <= ;
|
2007-09-20 18:09:08 -04:00
|
|
|
|
|
|
|
: wait-to-write ( len port -- )
|
2008-04-11 15:09:09 -04:00
|
|
|
tuck buffer>> can-write? [ drop ] [ stream-flush ] if ;
|
2007-09-20 18:09:08 -04:00
|
|
|
|
|
|
|
M: output-port stream-write1
|
2008-04-11 15:09:09 -04:00
|
|
|
1 over wait-to-write
|
|
|
|
buffer>> byte>buffer ;
|
2007-09-20 18:09:08 -04:00
|
|
|
|
|
|
|
M: output-port stream-write
|
2008-04-11 15:09:09 -04:00
|
|
|
over length over buffer>> buffer-size > [
|
|
|
|
[ buffer>> buffer-size <groups> ]
|
|
|
|
[ [ stream-write ] curry ] bi
|
|
|
|
each
|
2007-11-09 03:01:45 -05:00
|
|
|
] [
|
2008-04-11 15:09:09 -04:00
|
|
|
[ >r length r> wait-to-write ]
|
|
|
|
[ buffer>> >buffer ] 2bi
|
2007-11-09 03:01:45 -05:00
|
|
|
] if ;
|
2007-09-20 18:09:08 -04:00
|
|
|
|
2007-11-07 14:01:45 -05:00
|
|
|
GENERIC: port-flush ( port -- )
|
|
|
|
|
|
|
|
M: output-port stream-flush ( port -- )
|
2008-04-11 15:09:09 -04:00
|
|
|
[ port-flush ] [ pending-error ] bi ;
|
2007-11-07 14:01:45 -05:00
|
|
|
|
2008-02-01 16:00:02 -05:00
|
|
|
: close-port ( port type -- )
|
|
|
|
output-port eq? [ dup port-flush ] when
|
|
|
|
dup cancel-io
|
2008-04-11 15:09:09 -04:00
|
|
|
dup handle>> close-handle
|
|
|
|
[ [ buffer-free ] when* f ] change-buffer drop ;
|
2008-02-01 16:00:02 -05:00
|
|
|
|
2008-01-31 01:52:06 -05:00
|
|
|
M: port dispose
|
2008-04-11 15:09:09 -04:00
|
|
|
dup type>> closed eq?
|
2008-02-01 16:00:02 -05:00
|
|
|
[ drop ]
|
2008-04-11 15:09:09 -04:00
|
|
|
[ [ closed ] change-type swap close-port ]
|
2008-02-01 16:00:02 -05:00
|
|
|
if ;
|
2007-11-07 14:01:45 -05:00
|
|
|
|
2008-03-06 16:58:05 -05:00
|
|
|
TUPLE: server-port addr client client-addr encoding ;
|
2007-09-20 18:09:08 -04:00
|
|
|
|
2008-02-24 02:37:05 -05:00
|
|
|
: <server-port> ( handle addr encoding -- server )
|
2008-04-11 15:09:09 -04:00
|
|
|
rot server-port <port>
|
2008-02-24 02:37:05 -05:00
|
|
|
{ set-server-port-addr set-server-port-encoding set-delegate }
|
2007-09-20 18:09:08 -04:00
|
|
|
server-port construct ;
|
|
|
|
|
|
|
|
: check-server-port ( port -- )
|
|
|
|
port-type server-port assert= ;
|
|
|
|
|
|
|
|
TUPLE: datagram-port addr packet packet-addr ;
|
|
|
|
|
2008-01-21 15:33:43 -05:00
|
|
|
: <datagram-port> ( handle addr -- datagram )
|
2008-04-11 15:09:09 -04:00
|
|
|
>r datagram-port <port> r>
|
2007-09-20 18:09:08 -04:00
|
|
|
{ set-delegate set-datagram-port-addr }
|
|
|
|
datagram-port construct ;
|
|
|
|
|
|
|
|
: check-datagram-port ( port -- )
|
|
|
|
port-type datagram-port assert= ;
|
|
|
|
|
|
|
|
: check-datagram-send ( packet addrspec port -- )
|
|
|
|
dup check-datagram-port
|
2008-03-29 21:36:58 -04:00
|
|
|
datagram-port-addr [ class ] bi@ assert=
|
2007-09-20 18:09:08 -04:00
|
|
|
class byte-array assert= ;
|