X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=src%2Fcode%2Fstream.lisp;h=1e6dcdc86b1d39a8b395f6a2b8a593fc1919ecef;hb=97423182206cfe8c078eff105fea00dceb03be99;hp=1f43db72f981b90d01037525ee70f70e8393df53;hpb=4898ef32c639b1c7f4ee13a5ba566ce6debd03e6;p=sbcl.git diff --git a/src/code/stream.lisp b/src/code/stream.lisp index 1f43db7..1e6dcdc 100644 --- a/src/code/stream.lisp +++ b/src/code/stream.lisp @@ -223,33 +223,50 @@ (defun ansi-stream-read-line (stream eof-error-p eof-value recursive-p) (declare (ignore recursive-p)) (prepare-for-fast-read-char stream - (let ((res (make-string 80)) - (len 80) - (index 0)) - (loop - (let ((ch (fast-read-char nil nil))) - (cond (ch - (when (char= ch #\newline) - (done-with-fast-read-char) - (return (values (shrink-vector res index) nil))) - (when (= index len) - (setq len (* len 2)) - (let ((new (make-string len))) - (replace new res) - (setq res new))) - (setf (schar res index) ch) - (incf index)) - ((zerop index) - (done-with-fast-read-char) - (return (values (eof-or-lose stream - eof-error-p - eof-value) - t))) - ;; Since FAST-READ-CHAR already hit the eof char, we - ;; shouldn't do another READ-CHAR. - (t - (done-with-fast-read-char) - (return (values (shrink-vector res index) t))))))))) + ;; Check whether the FAST-READ-CHAR buffer contains a newline. If it + ;; does, we can do things quickly by just copying the line from the + ;; buffer instead of doing repeated calls to FAST-READ-CHAR. + (when %frc-buffer% + (locally + ;; For %FIND-POSITION transform + (declare (optimize (speed 2))) + (let ((pos (position #\Newline %frc-buffer% + :test #'char= + :start %frc-index%))) + (when pos + (let* ((len (- pos %frc-index%)) + (res (make-string len))) + (replace res %frc-buffer% :start2 %frc-index% :end2 pos) + (setf %frc-index% (1+ pos)) + (done-with-fast-read-char) + (return-from ansi-stream-read-line res)))))) + (let ((res (make-string 80)) + (len 80) + (index 0)) + (loop + (let ((ch (fast-read-char nil nil))) + (cond (ch + (when (char= ch #\newline) + (done-with-fast-read-char) + (return (values (%shrink-vector res index) nil))) + (when (= index len) + (setq len (* len 2)) + (let ((new (make-string len))) + (replace new res) + (setq res new))) + (setf (schar res index) ch) + (incf index)) + ((zerop index) + (done-with-fast-read-char) + (return (values (eof-or-lose stream + eof-error-p + eof-value) + t))) + ;; Since FAST-READ-CHAR already hit the eof char, we + ;; shouldn't do another READ-CHAR. + (t + (done-with-fast-read-char) + (return (values (%shrink-vector res index) t))))))))) (defun read-line (&optional (stream *standard-input*) (eof-error-p t) eof-value recursive-p) @@ -371,14 +388,13 @@ (done-with-fast-read-byte)))) (defun read-byte (stream &optional (eof-error-p t) eof-value) - (let ((stream (in-synonym-of stream))) - (if (ansi-stream-p stream) - (ansi-stream-read-byte stream eof-error-p eof-value nil) - ;; must be Gray streams FUNDAMENTAL-STREAM - (let ((char (stream-read-byte stream))) - (if (eq char :eof) - (eof-or-lose stream eof-error-p eof-value) - char))))) + (if (ansi-stream-p stream) + (ansi-stream-read-byte stream eof-error-p eof-value nil) + ;; must be Gray streams FUNDAMENTAL-STREAM + (let ((char (stream-read-byte stream))) + (if (eq char :eof) + (eof-or-lose stream eof-error-p eof-value) + char)))) ;;; Read NUMBYTES bytes into BUFFER beginning at START, and return the ;;; number of bytes read. @@ -596,8 +612,8 @@ nil) (defun write-byte (integer stream) - (with-out-stream stream (ansi-stream-bout integer) - (stream-write-byte integer)) + (with-out-stream/no-synonym stream (ansi-stream-bout integer) + (stream-write-byte integer)) integer)