Refactor int Encoders
Instead of Shifting bits and masking in order to extract a subset of the bits Lisp provides the function LBD, which allows us to extract a number of bits from an integer. This approach is more direct, communicates the intent better and allows the compiler to do less work.
This commit is contained in:
parent
85cc0ebeed
commit
26c7107ad3
1 changed files with 16 additions and 31 deletions
47
osc.lisp
47
osc.lisp
|
@ -352,20 +352,6 @@ with the current time use (encode-timetag :time)."
|
||||||
(ldb (byte 16 0) (decode-int32 s)))
|
(ldb (byte 16 0) (decode-int32 s)))
|
||||||
#-(or sbcl cmucl openmcl allegro) (error "cant decode floats using this implementation"))
|
#-(or sbcl cmucl openmcl allegro) (error "cant decode floats using this implementation"))
|
||||||
|
|
||||||
(defun encode-int32 (i)
|
|
||||||
"convert an integer into a sequence of 4 bytes in network byte order."
|
|
||||||
(declare (type integer i))
|
|
||||||
(let ((buf (make-sequence
|
|
||||||
'(vector (unsigned-byte 8)) 4)))
|
|
||||||
(macrolet ((set-byte (n)
|
|
||||||
`(setf (elt buf ,n)
|
|
||||||
(logand #xff (ash i ,(* 8 (- n 3)))))))
|
|
||||||
(set-byte 0)
|
|
||||||
(set-byte 1)
|
|
||||||
(set-byte 2)
|
|
||||||
(set-byte 3))
|
|
||||||
buf))
|
|
||||||
|
|
||||||
(defun decode-int32 (s)
|
(defun decode-int32 (s)
|
||||||
"4 byte -> 32 bit int -> two's compliment (in network byte order)"
|
"4 byte -> 32 bit int -> two's compliment (in network byte order)"
|
||||||
(let ((i (+ (ash (elt s 0) 24)
|
(let ((i (+ (ash (elt s 0) 24)
|
||||||
|
@ -384,24 +370,23 @@ with the current time use (encode-timetag :time)."
|
||||||
(elt s 3))))
|
(elt s 3))))
|
||||||
i))
|
i))
|
||||||
|
|
||||||
|
(defmacro defint-encoder (num-of-octets &optional docstring)
|
||||||
|
(let ((enc-name (intern (format nil "~:@(encode-int~)~D" (* 8 num-of-octets))))
|
||||||
|
(buf (gensym))
|
||||||
|
(int (gensym)))
|
||||||
|
`(defun ,enc-name (,int)
|
||||||
|
,@(when docstring
|
||||||
|
(list docstring))
|
||||||
|
(let ((,buf (make-array ,num-of-octets :element-type '(unsigned-byte 8))))
|
||||||
|
,@(loop
|
||||||
|
for n below num-of-octets
|
||||||
|
collect `(setf (aref ,buf ,n)
|
||||||
|
(ldb (byte 8 (* 8 (- (1- ,num-of-octets) ,n)))
|
||||||
|
,int)))
|
||||||
|
,buf))))
|
||||||
|
|
||||||
(defun encode-int64 (i)
|
(defint-encoder 4 "Convert an integer into a sequence of 4 bytes in network byte order.")
|
||||||
"convert an integer into a sequence of 8 bytes in network byte order."
|
(defint-encoder 8 "Convert an integer into a sequence of 8 bytes in network byte order.")
|
||||||
(declare (type integer i))
|
|
||||||
(let ((buf (make-sequence
|
|
||||||
'(vector (unsigned-byte 8)) 8)))
|
|
||||||
(macrolet ((set-byte (n)
|
|
||||||
`(setf (elt buf ,n)
|
|
||||||
(logand #xff (ash i ,(* 8 (- n 7)))))))
|
|
||||||
(set-byte 0)
|
|
||||||
(set-byte 1)
|
|
||||||
(set-byte 2)
|
|
||||||
(set-byte 3)
|
|
||||||
(set-byte 4)
|
|
||||||
(set-byte 5)
|
|
||||||
(set-byte 6)
|
|
||||||
(set-byte 7))
|
|
||||||
buf))
|
|
||||||
|
|
||||||
(defun decode-uint64 (s)
|
(defun decode-uint64 (s)
|
||||||
"8 byte -> 64 bit unsigned int"
|
"8 byte -> 64 bit unsigned int"
|
||||||
|
|
Loading…
Reference in a new issue