factor/library/unix/io.factor

151 lines
3.5 KiB
Factor
Raw Normal View History

! Copyright (C) 2005 Slava Pestov.
! See http://factor.sf.net/license.txt for BSD license.
IN: io-internals
USING: errors generic kernel math sequences strings ;
2005-04-09 00:09:49 -04:00
FORGET: can-read-line?
FORGET: can-read-count?
FORGET: can-write?
2005-04-08 23:50:36 -04:00
: file-mode OCT: 0600 ;
: io-error ( n -- ) 0 < [ errno strerror throw ] when ;
: open-read ( path -- fd )
O_RDONLY file-mode sys-open dup io-error ;
: open-write ( path -- fd )
O_WRONLY O_CREAT bitor O_TRUNC bitor file-mode sys-open
dup io-error ;
TUPLE: port handle buffer error ;
2005-04-03 18:28:55 -04:00
C: port ( handle buffer -- port )
2005-04-08 23:50:36 -04:00
[ >r <buffer> r> set-delegate ] keep
[ set-port-handle ] keep ;
2005-04-03 18:28:55 -04:00
: buffered-port 8192 <port> ;
2005-04-08 23:50:36 -04:00
: >port< dup port-handle swap delegate ;
2005-04-03 18:28:55 -04:00
2005-04-08 23:50:36 -04:00
: pending-error ( reader -- ) port-error throw ;
TUPLE: reader line ready? ;
C: reader ( handle -- reader )
[ >r buffered-port r> set-delegate ] keep ;
2005-04-03 18:28:55 -04:00
: read-line-loop ( line buffer -- ? )
2005-04-03 16:55:56 -04:00
dup buffer-length 0 = [
2drop f
] [
2005-04-05 22:18:36 -04:00
dup buffer-pop dup CHAR: \n = [
2005-04-03 16:55:56 -04:00
3drop t
] [
2005-04-05 22:18:36 -04:00
pick sbuf-append read-line-loop
2005-04-03 16:55:56 -04:00
] ifte
] ifte ;
: read-line-step ( reader -- ? )
[ dup reader-line swap read-line-loop dup ] keep
set-reader-ready? ;
2005-04-03 16:55:56 -04:00
2005-04-03 18:28:55 -04:00
: init-reader ( count reader -- ) >r <sbuf> r> set-reader-line ;
2005-04-03 16:55:56 -04:00
: prepare-line ( reader -- ? )
80 over init-reader read-line-step ;
2005-04-03 16:55:56 -04:00
: can-read-line? ( reader -- ? )
2005-04-03 18:28:55 -04:00
dup pending-error
2005-04-03 16:55:56 -04:00
dup reader-ready? [ drop t ] [ prepare-line ] ifte ;
: reader-eof ( reader -- )
dup reader-line dup [
2005-04-03 18:28:55 -04:00
length 0 = [ f over set-reader-line ] when
2005-04-03 16:55:56 -04:00
] [
drop
] ifte t swap set-reader-ready? ;
2005-04-03 18:28:55 -04:00
2005-04-08 23:50:36 -04:00
: read-step ( port -- ? )
>port<
tuck dup buffer-end swap buffer-capacity sys-read
dup 0 >= [ swap n>buffer t ] [ 2drop f ] ifte ;
2005-04-03 18:28:55 -04:00
: refill ( reader -- )
2005-04-08 23:50:36 -04:00
dup buffer-length 0 = [
read-step drop
] [
drop
] ifte ;
2005-04-03 18:28:55 -04:00
2005-04-08 23:50:36 -04:00
: eof? ( buffer -- ? ) buffer-fill 0 = ;
2005-04-03 18:28:55 -04:00
: read-count-step ( count reader -- ? )
dup reader-line -rot >r over length - r>
2dup buffer-fill <= [
2005-04-03 18:28:55 -04:00
buffer> swap sbuf-append t
] [
buffer>> nip swap sbuf-append f
] ifte ;
: can-read-count? ( count reader -- ? )
dup pending-error
2dup reader-line length >= [
2drop t
] [
2dup init-reader read-count-step
] ifte ;
: pop-line ( reader -- str )
2005-04-05 22:18:36 -04:00
dup reader-line dup [ sbuf>string ] when >r
2005-04-03 18:28:55 -04:00
f over set-reader-line
f swap set-reader-ready? r> ;
: read-fin ( reader -- str )
dup pending-error dup reader-ready? [
pop-line
] [
"reader not ready" throw
] ifte ;
2005-04-08 23:50:36 -04:00
TUPLE: writer ;
2005-04-08 23:50:36 -04:00
C: writer ( fd -- writer )
[ >r buffered-port r> set-delegate ] keep ;
: write-step ( fd buffer -- ? )
tuck dup buffer@ swap buffer-length sys-write
2005-04-08 23:50:36 -04:00
dup 0 >= [ swap buffer-consume t ] [ 2drop f ] ifte ;
: can-write? ( len writer -- ? )
#! If the buffer is empty and the string is too long,
#! extend the buffer.
dup pending-error
2005-04-08 23:50:36 -04:00
dup eof? >r 2dup buffer-capacity > r> and [
buffer-extend t
] [
[ buffer-fill + ] keep buffer-capacity <=
] ifte ;
: write-fin ( str writer -- )
dup pending-error
>r dup string? [ ch>string ] unless r> >buffer ;
2005-04-08 23:50:36 -04:00
: can-copy? ( from -- ? )
dup eof? [ read-step ] [ drop t ] ifte ;
: copy-from-task ( from to -- ? )
over can-copy? [
over eof? [
2drop t
] [
over buffer-fill over can-write? [
2005-04-09 00:09:49 -04:00
dupd buffer-append 0 swap buffer-reset
2005-04-08 23:50:36 -04:00
] [
2drop
] ifte f
] ifte
] [
2drop f
] ifte ;