Commit d102838a authored by Nathan Froyd's avatar Nathan Froyd
Browse files

add interfaces for reading vectors of values

I'm happy about the functionality; I'm not satisfied with the names,
because I also want to add destructive versions of these ala
READ-SEQUENCE.  But we can tinker with that later.
parent fb472c59
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -18,6 +18,11 @@
    (intern (format nil "~:[WRITE~;READ~]-~:[U~;S~]B~D/~:[LE~;BE~]"
                    readp signedp bitsize big-endian-p))))

(defun stream-vector-fun-name (bitsize readp signedp big-endian-p)
  (let ((*package* (find-package :nibbles)))
    (intern (format nil "~:[WRITE~;READ~]-~:[U~;S~]B~D/~:[LE~;BE~]-VECTOR"
		    readp signedp bitsize big-endian-p))))

(defun internalify (s)
  (let ((*package* (find-package :nibbles)))
    (intern (concatenate 'string "%" (string s)))))
+7 −0
Original line number Diff line number Diff line
@@ -12,6 +12,13 @@
  (:export #:read-ub16/le #:read-ub16/be #:read-sb16/be #:read-sb16/le
           #:read-ub32/le #:read-ub32/be #:read-sb32/be #:read-sb32/le
           #:read-ub64/le #:read-ub64/be #:read-sb64/be #:read-sb64/le)
  ;; Stream readers for vectors.
  (:export #:read-ub16/le-vector #:read-ub16/be-vector
	   #:read-sb16/le-vector #:read-sb16/le-vector
	   #:read-ub32/le-vector #:read-ub32/be-vector
	   #:read-sb32/le-vector #:read-sb32/be-vector
	   #:read-ub64/le-vector #:read-ub64/be-vector
	   #:read-sb64/le-vector #:read-sb64/be-vector)
  ;; Stream writers.
  (:export #:write-ub16/le #:write-ub16/be #:write-sb16/be #:write-sb16/le
           #:write-ub32/le #:write-ub32/be #:write-sb32/be #:write-sb32/le
+21 −3
Original line number Diff line number Diff line
@@ -24,6 +24,16 @@
    (write-sequence v stream)
    integer))

(declaim (inline read-into-vector*))
(defun read-into-vector* (stream vector start end n-bytes reffer)
  (declare (type function reffer))
  (let ((v (make-array n-bytes :element-type '(unsigned-byte 8))))
    (declare (dynamic-extent v))
    (loop for i from start below end
	  do (read-n-bytes-into stream n-bytes v)
	     (setf (aref vector i) (funcall reffer v 0))
	  finally (return vector))))

#.(loop for i from 0 upto #b10111
        for bitsize = (ecase (ldb (byte 2 3) i)
                        (0 16)
@@ -37,8 +47,16 @@
	for byte-fun = (if readp
			   (byte-ref-fun-name bitsize signedp big-endian-p)
			   (byte-set-fun-name bitsize signedp big-endian-p))
	for arglist = (if readp '(stream) '(integer stream))
	for byte-arglist = (if readp '(stream) '(integer stream))
	for subfun = (if readp 'read-byte* 'write-byte*)
        collect `(defun ,name ,arglist
		   (,subfun ,@arglist ,n-bytes #',byte-fun)) into forms
	for element-type = `(,(if signedp 'signed-byte 'unsigned-byte) ,bitsize)
        collect `(defun ,name ,byte-arglist
		   (,subfun ,@byte-arglist ,n-bytes #',byte-fun)) into forms
	if readp
	  collect `(defun ,(stream-vector-fun-name bitsize t signedp big-endian-p)
		       (stream n-elements)
		     (let ((vector (make-array n-elements
					       :element-type ',element-type)))
		       (read-into-vector* stream vector 0 n-elements
					  ,n-bytes #',byte-fun))) into forms
        finally (return `(progn ,@forms)))