X-Git-Url: http://git.kpe.io/?p=kmrcl.git;a=blobdiff_plain;f=buff-input.lisp;h=1f2b2f6297fcb98fc495cdb1f4d6c6e1d73d6124;hp=f0802bc0bff2b141479a24a27668c0c7ab7fbf57;hb=54cd6cb1b9550ac2310e2c6dffc9cdecd2bdccd3;hpb=8d831065b8e830ea8b257aa7befd53bee7f49d5d diff --git a/buff-input.lisp b/buff-input.lisp index f0802bc..1f2b2f6 100644 --- a/buff-input.lisp +++ b/buff-input.lisp @@ -7,8 +7,6 @@ ;;;; Programmer: Kevin M. Rosenberg ;;;; Date Started: Apr 2000 ;;;; -;;;; $Id: buff-input.lisp,v 1.5 2003/05/05 19:54:14 kevin Exp $ -;;;; ;;;; This file, part of KMRCL, is Copyright (c) 2002 by Kevin M. Rosenberg ;;;; ;;;; KMRCL users are granted the rights to distribute and use this software @@ -28,117 +26,119 @@ (defconstant +newline+ #\Newline) (declaim (type character +eof-char+ +field-delim+ +newline+) - (type fixnum +max-field+ +max-fields-per-line+)) + (type fixnum +max-field+ +max-fields-per-line+)) ;; Buffered fields parsing function ;; Uses fill-pointer for size -(defun make-fields-buffer (&optional (max-fields +max-fields-per-line+) - (max-field-len +max-field+)) +(defun make-fields-buffer (&optional (max-fields +max-fields-per-line+) + (max-field-len +max-field+)) (let ((bufs (make-array max-fields :element-type 'vector :fill-pointer 0 :adjustable nil))) (dotimes (i +max-fields-per-line+) (setf (aref bufs i) (make-array max-field-len :element-type 'character :fill-pointer 0 :adjustable nil))) bufs)) -(defun read-buffered-fields (fields strm &optional (field-delim +field-delim+)) +(defun read-buffered-fields (fields strm &optional (field-delim +field-delim+) + (eof 'eof)) "Read a line from a stream into a field buffers" (declare (type base-char field-delim) - (type vector fields)) + (type vector fields)) (setf (fill-pointer fields) 0) (do ((ifield 0 (1+ ifield)) (linedone nil) - (eof nil)) - (linedone (if eof 'eof fields)) + (is-eof nil)) + (linedone (if is-eof eof fields)) (declare (type fixnum ifield) - (type boolean linedone eof)) + (type boolean linedone is-eof)) (let ((field (aref fields ifield))) (declare (type base-string field)) (do ((ipos 0) - (fielddone nil) - (rc (read-char strm nil +eof-char+) - (read-char strm nil +eof-char+))) - (fielddone (unread-char rc strm)) - (declare (type fixnum ipos) - (type base-char rc) - (type boolean fielddone)) - (cond - ((char= rc field-delim) - (setf (fill-pointer field) ipos) - (setq fielddone t)) - ((char= rc +newline+) - (setf (fill-pointer field) ipos) - (setf (fill-pointer fields) ifield) - (setq fielddone t) - (setq linedone t)) - ((char= rc +eof-char+) - (setf (fill-pointer field) ipos) - (setf (fill-pointer fields) ifield) - (setq fielddone t) - (setq linedone t) - (setq eof t)) - (t - (setf (char field ipos) rc) - (incf ipos))))))) + (fielddone nil) + (rc (read-char strm nil +eof-char+) + (read-char strm nil +eof-char+))) + (fielddone (unread-char rc strm)) + (declare (type fixnum ipos) + (type base-char rc) + (type boolean fielddone)) + (cond + ((char= rc field-delim) + (setf (fill-pointer field) ipos) + (setq fielddone t)) + ((char= rc +newline+) + (setf (fill-pointer field) ipos) + (setf (fill-pointer fields) ifield) + (setq fielddone t) + (setq linedone t)) + ((char= rc +eof-char+) + (setf (fill-pointer field) ipos) + (setf (fill-pointer fields) ifield) + (setq fielddone t) + (setq linedone t) + (setq is-eof t)) + (t + (setf (char field ipos) rc) + (incf ipos))))))) ;; Buffered fields parsing ;; Does not use fill-pointer ;; Returns 2 values -- string array and length array -(defstruct field-buffers +(defstruct field-buffers (nfields 0 :type fixnum) (buffers) (field-lengths)) -(defun make-fields-buffer2 (&optional (max-fields +max-fields-per-line+) - (max-field-len +max-field+)) +(defun make-fields-buffer2 (&optional (max-fields +max-fields-per-line+) + (max-field-len +max-field+)) (let ((bufs (make-array max-fields :element-type 'vector :fill-pointer nil :adjustable nil)) - (bufstruct (make-field-buffers))) + (bufstruct (make-field-buffers))) (dotimes (i +max-fields-per-line+) (setf (aref bufs i) (make-array max-field-len :element-type 'character :fill-pointer nil :adjustable nil))) (setf (field-buffers-buffers bufstruct) bufs) - (setf (field-buffers-field-lengths bufstruct) (make-array +max-fields-per-line+ - :element-type 'fixnum :fill-pointer nil :adjustable nil)) + (setf (field-buffers-field-lengths bufstruct) (make-array +max-fields-per-line+ + :element-type 'fixnum :fill-pointer nil :adjustable nil)) (setf (field-buffers-nfields bufstruct) 0) bufstruct)) -(defun read-buffered-fields2 (fields strm &optional (field-delim +field-delim+)) +(defun read-buffered-fields2 (fields strm &optional (field-delim +field-delim+) + (eof 'eof)) "Read a line from a stream into a field buffers" (declare (character field-delim)) (setf (field-buffers-nfields fields) 0) (do ((ifield 0 (1+ ifield)) (linedone nil) - (eof nil)) - (linedone (if eof 'eof fields)) + (is-eof nil)) + (linedone (if is-eof eof fields)) (declare (fixnum ifield) - (t linedone eof)) + (t linedone is-eof)) (let ((field (aref (field-buffers-buffers fields) ifield))) (declare (simple-string field)) (do ((ipos 0) - (fielddone nil) - (rc (read-char strm nil +eof-char+) - (read-char strm nil +eof-char+))) - (fielddone (unread-char rc strm)) - (declare (fixnum ipos) - (character rc) - (t fielddone)) - (cond - ((char= rc field-delim) - (setf (aref (field-buffers-field-lengths fields) ifield) ipos) - (setq fielddone t)) - ((char= rc +newline+) - (setf (aref (field-buffers-field-lengths fields) ifield) ipos) - (setf (field-buffers-nfields fields) ifield) - (setq fielddone t) - (setq linedone t)) - ((char= rc +eof-char+) - (setf (aref (field-buffers-field-lengths fields) ifield) ipos) - (setf (field-buffers-nfields fields) ifield) - (setq fielddone t) - (setq linedone t) - (setq eof t)) - (t - (setf (char field ipos) rc) - (incf ipos))))))) + (fielddone nil) + (rc (read-char strm nil +eof-char+) + (read-char strm nil +eof-char+))) + (fielddone (unread-char rc strm)) + (declare (fixnum ipos) + (character rc) + (t fielddone)) + (cond + ((char= rc field-delim) + (setf (aref (field-buffers-field-lengths fields) ifield) ipos) + (setq fielddone t)) + ((char= rc +newline+) + (setf (aref (field-buffers-field-lengths fields) ifield) ipos) + (setf (field-buffers-nfields fields) ifield) + (setq fielddone t) + (setq linedone t)) + ((char= rc +eof-char+) + (setf (aref (field-buffers-field-lengths fields) ifield) ipos) + (setf (field-buffers-nfields fields) ifield) + (setq fielddone t) + (setq linedone t) + (setq is-eof t)) + (t + (setf (char field ipos) rc) + (incf ipos))))))) (defun bfield (fields i) (if (>= i (field-buffers-nfields fields)) @@ -149,28 +149,32 @@ (defconstant +max-line+ 20000) (let ((linebuffer (make-array +max-line+ - :element-type 'character - :fill-pointer 0))) - (defun read-buffered-line (strm) + :element-type 'character + :fill-pointer 0))) + (defun read-buffered-line (strm eof) "Read a line from astream into a vector buffer" + (declare (optimize (speed 3) (space 0) (safety 0))) (let ((pos 0) - (done nil)) - (declare (fixnum pos) (t done)) + (done nil)) + (declare (fixnum pos) (type boolean done)) (setf (fill-pointer linebuffer) 0) (do ((c (read-char strm nil +eof-char+) - (read-char strm nil +eof-char+))) - (done (progn - (unless (eql c +eof-char+) (unread-char c strm)) - (if (eql c +eof-char+) 'eof linebuffer))) - (declare (character c)) - (cond - ((char= c #\Newline) - (unless (zerop pos) - (setf (fill-pointer linebuffer) (1- pos))) - (setf done t)) - ((char= +eof-char+) - (setf done t)) - (t - (setf (char linebuffer pos) c) - (incf pos))))))) + (read-char strm nil +eof-char+))) + (done (progn + (unless (eql c +eof-char+) (unread-char c strm)) + (if (eql c +eof-char+) eof linebuffer))) + (declare (character c)) + (cond + ((>= pos +max-line+) + (warn "Line overflow") + (setf done t)) + ((char= c #\Newline) + (when (plusp pos) + (setf (fill-pointer linebuffer) (1- pos))) + (setf done t)) + ((char= +eof-char+) + (setf done t)) + (t + (setf (char linebuffer pos) c) + (incf pos)))))))