racket-ssh-2012/safe-io.rkt

29 lines
911 B
Racket

#lang racket/base
(provide read-line-limited)
;; Port Natural -> (or String EofObject)
;; Uses Internet (CRLF) convention. Limit does not cover the CRLF
;; bytes.
(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))))))