Skip to content

Instantly share code, notes, and snippets.

@stassats
Created June 7, 2024 18:00
Show Gist options
  • Save stassats/e33a38233565102873778c2aae7e81a8 to your computer and use it in GitHub Desktop.
Save stassats/e33a38233565102873778c2aae7e81a8 to your computer and use it in GitHub Desktop.
(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