Created
June 7, 2024 18:00
-
-
Save stassats/e33a38233565102873778c2aae7e81a8 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(defun map-csv-file (fun file) | |
(let ((buffer (make-string 512))) | |
(with-open-file (stream file) | |
(let (fields | |
(read 0) | |
(start 0) | |
concat | |
escaping) | |
(loop | |
do | |
(setf read (read-sequence buffer stream) | |
start 0) | |
(loop for n below read | |
for char = (aref buffer n) | |
do (flet ((end-field () | |
(let ((field (subseq buffer start n))) | |
(when concat | |
(push field concat) | |
(setf field (apply #'concatenate 'string (nreverse concat)) | |
concat nil)) | |
(push field fields)))) | |
(if escaping | |
(case char | |
(#\" | |
(end-field) | |
(setf escaping nil) | |
(setf start (1+ n)))) | |
(case char | |
(#\Return | |
(when (or concat | |
(> n start)) | |
(end-field)) | |
(funcall fun (nreverse fields)) | |
(setf fields nil) | |
(setf start (1+ n))) | |
(#\Newline | |
(setf start (1+ n))) | |
(#\, | |
(end-field) | |
(setf start (1+ n))) | |
(#\" | |
(setf escaping t) | |
(setf start (1+ n))))))) | |
(when (> read start) | |
(push (subseq buffer start read) | |
concat)) | |
while (= read (length buffer))))))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment