John, Matthew,

Thanks for your suggestions. I have chosen Matthew's one, as it
seems to be more general. I only had to cancel the peek operation
filtering, as I sometimes use (eof-object? (peek-byte)) to test
for EOF (is there any other way?), so throwing an exception in
that case is not desirable. Here is how it is now:

(filter-read-input-port
   p
   (lambda (bstr r) (filter-result r))
   (lambda (bstr offset evt r) r)
   #t)

Best regards,

Dmitry

On 12/27/2011 02:39 AM, Matthew Flatt wrote:
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 #""))))
____________________
 Racket Users list:
 http://lists.racket-lang.org/users

Reply via email to