[racket] exception instead of EOF?
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 #""))))