[racket] exception instead of EOF?
Here's another approach, which is to wrap the port with one that raises
an exception before returning an EOF on read or peek:
#lang racket
(define (input-port->error-eof-input-port p [close? #t])
(define (handle-eof) (error "eof"))
(define (filter-result r)
(cond
[(eof-object? r) (handle-eof)]
[(evt? r) (wrap-evt r
(lambda (r)
(if (eof-object? r)
(handle-eof)
r)))]
[else r]))
(filter-read-input-port
p
(lambda (bstr r)
(filter-result r))
(lambda (bstr offset evt r)
(filter-result r))
close?))
(define p (open-input-bytes #"apple"))
(define p2 (input-port->error-eof-input-port p))
(read-bytes 5 p2) ; ok
(read-byte p2) ; fail
At Mon, 26 Dec 2011 08:06:47 -0800, John Clements wrote:
>
> On Dec 26, 2011, at 2:46 AM, Dmitry Pavlov wrote:
>
> > Hello,
> >
> > I would like to make read-byte and friends to
> > throw an exception in case end of file is
> > reached. That is, when I call read-byte,
> > I know that the byte must be there, otherwise
> > the input data is corrupt. I would prefer
> > not to check the result of every read-byte
> > call. What is the simplest way to achieve
> > such a behavior?
>
> I would just write a procedure that checks to see a byte is not an eof-object,
> and signals an error if required. Like this (including test cases):
>
> #lang racket
>
> (require rackunit)
>
> ;; given a stream, reads a byte, signalling
> ;; an error at the end of the file.
> (define (read-byte/exn input-stream)
> (define result (read-byte input-stream))
> (cond [(eof-object? result)
> (error 'read-byte/exn "expected byte, got #<eof>")]
> [else result]))
>
> (check-equal? (read-byte/exn (open-input-bytes #"ABC")) 65)
> (check-exn exn:fail?
> (lambda () (read-byte/exn (open-input-bytes #""))))