>>28
If you insist. I didn't have any handy code which does actual byteswapping as the data was read in in the proper endianess in the first place without requiring further swapping, but as the task itself is easy, I wrote this code to illustrate how to implement such a thing:
;;; Utilities
(defmacro with-gensyms ((&rest names) &body body)
`(let ,(loop for name in names collect `(,name (gensym ,(string name))))
,@body))
(eval-when (:compile-toplevel :load-toplevel :execute)
(defun symbolicate (syms &optional (package *package*))
(intern (apply #'concatenate 'string (mapcar #'string syms)) package)))
;;; Implementation
(defmacro define-byte-swapper
(name &key (byte-count 4) (byte-size 8))
(with-gensyms (int)
`(progn
(declaim (inline ,name))
(defun ,name (,int)
(logior
,@(loop for i from 0 below byte-count collect
`(ash
(logand
,(ash (1- (ash 1 byte-size)) (* i byte-size)) ,int)
,(* byte-size (- (1- byte-count) (* i 2))))))))))
(defmacro define-byte-swappers (&key (up-to-powers-of-2-bytes 5)
(byte-size 8))
`(progn ,@(loop for i from 1 to up-to-powers-of-2-bytes collect
`(define-byte-swapper
,(symbolicate
`(bswap ,(format nil "~D" (* byte-size (ash 1 i)))))
:byte-count ,(ash 1 i)))))
;; defines bswap16 to bswap256
(define-byte-swappers)
;;; Test
(setf *print-base* 16 *print-radix* t)
(values (bswap16 #x1122) (bswap32 #x11223344) (bswap64 #x1122334455667788) (bswap128 #x1122334455667788AABBCCDDEEFF1234) (bswap256 #x1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF)) ; =>
#x2211
#x44332211
#x8877665544332211
#x3412FFEEDDCCBBAA8877665544332211
#xEFCDAB9078563412EFCDAB9078563412EFCDAB9078563412EFCDAB9078563412
If this were not meant to be an example, some of those
defmacro's would be written as
macrolet's and the inner
defun may be written as a compiler macro or as a macro (if support for old implementation which can't inline is to be considered), but the difference in the implementation is too small to be worth showing, so only this inlining version is shown.