add filter-read-input-port' to racket/port'

This commit is contained in:
Matthew Flatt 2011-01-24 14:45:29 -07:00
parent 28351c1795
commit ce2d6030c7
2 changed files with 65 additions and 0 deletions

View File

@ -478,6 +478,35 @@
count-lines!-proc
pos)))
(define filter-read-input-port
(lambda (p wrap-read wrap-peek [close? #t])
(make-input-port
(object-name p)
(lambda (s)
(let ([v (read-bytes-avail!* s p)])
(wrap-read
s
(if (eq? v 0) (wrap-evt p (lambda (x) 0)) v))))
(lambda (s skip evt)
(let ([v (peek-bytes-avail!* s skip evt p)])
(wrap-peek
s skip evt
(if (eq? v 0)
(choice-evt
(wrap-evt p (lambda (x) 0))
(if evt (wrap-evt evt (lambda (x) #f)) never-evt))
v))))
(lambda ()
(when close? (close-input-port p)))
(and (port-provides-progress-evts? p)
(lambda () (port-progress-evt p)))
(and (port-provides-progress-evts? p)
(lambda (n evt target-evt) (port-commit-peeked n evt target-evt p)))
(lambda () (port-next-location p))
(lambda () (port-count-lines! p))
(let-values ([(line col pos) (port-next-location p)])
(or pos (file-position p))))))
;; Not kill-safe.
(define make-pipe-with-specials
;; This implementation of pipes is almost CML-style, with a manager thread
@ -1732,6 +1761,7 @@
peeking-input-port
relocate-input-port
transplant-input-port
filter-read-input-port
special-filter-input-port
relocate-output-port
transplant-output-port

View File

@ -506,6 +506,41 @@ is enabled for the resulting port. The default is @scheme[void].}
Like @scheme[transplant-input-port], but for output ports.}
@defproc[(filter-read-input-port [in input-port?]
[read-wrap (bytes? (or/c exact-nonnegative-integer?
eof-object?
procedure?
evt?)
. -> .
(or/c exact-nonnegative-integer?
eof-object?
procedure?
evt?))]
[peek-wrap (bytes? exact-nonnegative-integer? (or/c evt? #f)
(or/c exact-nonnegative-integer?
eof-object?
procedure?
evt?
#f)
. -> . (or/c exact-nonnegative-integer?
eof-object?
procedure?
evt?
#f))]
[close? any/c #t])
input-port?]{
Creates a port that draws from @racket[in], but each result from the
port's read and peek procedures (in the sense of @racket[make-input-port])
is filtered by @racket[read-wrap] and
@racket[peek-wrap]. The filtering procedures each receive both the
arguments and results of the read and peek procedures on @racket[in]
for each call.
If @racket[close?] is true, then closing the resulting port also
closes @racket[in].}
@defproc[(special-filter-input-port [in input-port?]
[proc (procedure? bytes? . -> . (or/c exact-nonnegative-integer?
eof-object?