]> gitweb.factorcode.org Git - factor.git/blob - basis/io/ports/ports.factor
Fix permission bits
[factor.git] / basis / io / ports / ports.factor
1 ! Copyright (C) 2005, 2008 Slava Pestov, Doug Coleman
2 ! See http://factorcode.org/license.txt for BSD license.
3 USING: math kernel io sequences io.buffers io.timeouts generic
4 byte-vectors system io.encodings math.order io.backend
5 continuations debugger classes byte-arrays namespaces splitting
6 grouping dlists assocs io.encodings.binary summary accessors
7 destructors combinators ;
8 IN: io.ports
9
10 SYMBOL: default-buffer-size
11 64 1024 * default-buffer-size set-global
12
13 TUPLE: port handle timeout disposed ;
14
15 M: port timeout timeout>> ;
16
17 M: port set-timeout (>>timeout) ;
18
19 : <port> ( handle class -- port )
20     new swap >>handle ; inline
21
22 TUPLE: buffered-port < port { buffer buffer } ;
23
24 : <buffered-port> ( handle class -- port )
25     <port>
26         default-buffer-size get <buffer> >>buffer ; inline
27
28 TUPLE: input-port < buffered-port ;
29
30 : <input-port> ( handle -- input-port )
31     input-port <buffered-port> ;
32
33 HOOK: (wait-to-read) io-backend ( port -- )
34
35 : wait-to-read ( port -- eof? )
36     dup buffer>> buffer-empty? [
37         dup (wait-to-read) buffer>> buffer-empty?
38     ] [ drop f ] if ; inline
39
40 M: input-port stream-read1
41     dup check-disposed
42     dup wait-to-read [ drop f ] [ buffer>> buffer-pop ] if ;
43
44 : read-step ( count port -- byte-array/f )
45     dup wait-to-read [ 2drop f ] [ buffer>> buffer-read ] if ;
46
47 M: input-port stream-read-partial ( max stream -- byte-array/f )
48     dup check-disposed
49     >r 0 max >integer r> read-step ;
50
51 : read-loop ( count port accum -- )
52     pick over length - dup 0 > [
53         pick read-step dup [
54             over push-all read-loop
55         ] [
56             2drop 2drop
57         ] if
58     ] [
59         2drop 2drop
60     ] if ;
61
62 M: input-port stream-read
63     dup check-disposed
64     >r 0 max >fixnum r>
65     2dup read-step dup [
66         pick over length > [
67             pick <byte-vector>
68             [ push-all ] keep
69             [ read-loop ] keep
70             B{ } like
71         ] [ 2nip ] if
72     ] [ 2nip ] if ;
73
74 : read-until-step ( separators port -- string/f separator/f )
75     dup wait-to-read [ 2drop f f ] [ buffer>> buffer-until ] if ;
76
77 : read-until-loop ( seps port buf -- separator/f )
78     2over read-until-step over [
79         >r over push-all r> dup [
80             >r 3drop r>
81         ] [
82             drop read-until-loop
83         ] if
84     ] [
85         >r 2drop 2drop r>
86     ] if ;
87
88 M: input-port stream-read-until ( seps port -- str/f sep/f )
89     2dup read-until-step dup [ >r 2nip r> ] [
90         over [
91             drop
92             BV{ } like [ read-until-loop ] keep B{ } like swap
93         ] [ >r 2nip r> ] if
94     ] if ;
95
96 TUPLE: output-port < buffered-port ;
97
98 : <output-port> ( handle -- output-port )
99     output-port <buffered-port> ;
100
101 : wait-to-write ( len port -- )
102     tuck buffer>> buffer-capacity <=
103     [ drop ] [ stream-flush ] if ;
104
105 M: output-port stream-write1
106     dup check-disposed
107     1 over wait-to-write
108     buffer>> byte>buffer ;
109
110 M: output-port stream-write
111     dup check-disposed
112     over length over buffer>> size>> > [
113         [ buffer>> size>> <groups> ]
114         [ [ stream-write ] curry ] bi
115         each
116     ] [
117         [ >r length r> wait-to-write ]
118         [ buffer>> >buffer ] 2bi
119     ] if ;
120
121 HOOK: (wait-to-write) io-backend ( port -- )
122
123 GENERIC: shutdown ( handle -- )
124
125 M: object shutdown drop ;
126
127 : port-flush ( port -- )
128     dup buffer>> buffer-empty?
129     [ drop ] [ dup (wait-to-write) port-flush ] if ;
130
131 M: output-port stream-flush ( port -- )
132     [ check-disposed ] [ port-flush ] bi ;
133
134 M: output-port dispose*
135     [
136         {
137             [ handle>> &dispose drop ]
138             [ buffer>> &dispose drop ]
139             [ port-flush ]
140             [ handle>> shutdown ]
141         } cleave
142     ] with-destructors ;
143
144 M: buffered-port dispose*
145     [ call-next-method ] [ buffer>> dispose ] bi ;
146
147 M: port cancel-operation handle>> cancel-operation ;
148
149 M: port dispose*
150     [
151         [ handle>> &dispose drop ]
152         [ handle>> shutdown ]
153         bi
154     ] with-destructors ;
155
156 ! Fast-path optimization
157 USING: hints strings io.encodings.utf8 io.encodings.ascii
158 io.encodings.private ;
159
160 HINTS: decoder-read-until { string input-port utf8 } { string input-port ascii } ;
161
162 HINTS: decoder-readln { input-port utf8 } { input-port ascii } ;
163
164 HINTS: decoder-write { string output-port utf8 } { string output-port ascii } ;