1 ! Copyright (C) 2005, 2009 Slava Pestov.
2 ! See https://factorcode.org/license.txt for BSD license.
3 USING: accessors delegate delegate.protocols destructors effects
4 io io.encodings io.ports io.styles io.timeouts kernel ;
7 TUPLE: duplex-stream in out ;
9 C: <duplex-stream> duplex-stream
11 CONSULT: input-stream-protocol duplex-stream in>> ;
12 CONSULT: output-stream-protocol duplex-stream out>> ;
13 CONSULT: formatted-output-stream-protocol duplex-stream out>> ;
15 INSTANCE: duplex-stream input-stream
16 INSTANCE: duplex-stream output-stream
18 : >duplex-stream< ( stream -- in out ) in-out ; inline
20 M: duplex-stream stream-element-type
22 [ stream-element-type ] bi@
23 2dup eq? [ drop ] [ "Cannot determine element type" throw ] if ;
25 M: duplex-stream set-timeout
26 >duplex-stream< [ set-timeout ] bi-curry@ bi ;
28 M: duplex-stream dispose
29 ! The output stream is closed first, in case both streams
30 ! are attached to the same file descriptor, the output
31 ! buffer needs to be flushed before we close the fd.
32 [ >duplex-stream< [ &dispose drop ] bi@ ] with-destructors ;
34 : <encoder-duplex> ( stream-in stream-out encoding -- duplex )
35 [ re-decode ] [ re-encode ] bi-curry bi* <duplex-stream> ;
37 : with-stream* ( stream quot -- )
38 [ >duplex-stream< ] dip with-streams* ; inline
40 : with-stream ( stream quot -- )
41 [ >duplex-stream< ] dip with-streams ; inline
43 ERROR: invalid-duplex-stream ;
45 M: duplex-stream underlying-handle
47 [ underlying-handle ] bi@
48 [ = [ invalid-duplex-stream ] when ] keep ;