Length-limited line reading
This commit is contained in:
parent
0b60d73f64
commit
3ffa667e89
|
@ -0,0 +1,26 @@
|
|||
#lang racket/base
|
||||
|
||||
(provide read-line-limited)
|
||||
|
||||
;; Uses Internet (CRLF) convention.
|
||||
(define (read-line-limited port limit)
|
||||
(let collect-chars ((acc '())
|
||||
(remaining limit))
|
||||
(let ((ch (read-char port)))
|
||||
(cond
|
||||
((eof-object? ch) (if (null? acc)
|
||||
ch
|
||||
(list->string (reverse acc))))
|
||||
((eqv? ch #\return) (let ((ch (read-char port)))
|
||||
(if (eqv? ch #\linefeed)
|
||||
(list->string (reverse acc))
|
||||
(error 'read-line-limited
|
||||
"Invalid character ~v after #\\return"
|
||||
ch))))
|
||||
((eqv? ch #\newline)
|
||||
;; Is this a good idea?
|
||||
(error 'read-line-limited "Bare #\\linefeed encountered"))
|
||||
((positive? remaining) (collect-chars (cons ch acc) (- remaining 1)))
|
||||
(else (error 'read-line-limited
|
||||
"Line too long (more than ~v bytes before CRLF)"
|
||||
limit))))))
|
|
@ -0,0 +1,23 @@
|
|||
#lang racket/base
|
||||
|
||||
(require "safe-io.rkt")
|
||||
(require rackunit)
|
||||
|
||||
(define (s str)
|
||||
(open-input-string str))
|
||||
|
||||
(check-equal? (read-line-limited (s "") 5) eof)
|
||||
(check-equal? (read-line-limited (s "abc") 5) "abc")
|
||||
(check-equal? (read-line-limited (s "abc\r\ndef") 5) "abc")
|
||||
(check-equal? (read-line-limited (s "abcxy\r\ndef") 5) "abcxy")
|
||||
|
||||
(check-exn #rx"read-line-limited: Invalid character #<eof> after #\\\\return"
|
||||
(lambda () (read-line-limited (s "abc\r") 5)))
|
||||
(check-exn #rx"read-line-limited: Invalid character #\\\\d after #\\\\return"
|
||||
(lambda () (read-line-limited (s "abc\rdef") 5)))
|
||||
|
||||
(check-exn #rx"Bare #\\\\linefeed encountered"
|
||||
(lambda () (read-line-limited (s "abc\ndef") 5)))
|
||||
|
||||
(check-exn #rx"Line too long \\(more than 5 bytes before CRLF\\)"
|
||||
(lambda () (read-line-limited (s "abcxyz\r\ndef") 5)))
|
Loading…
Reference in New Issue