Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- (defvar *byte-buffer* nil)
- (defvar *bit-buffer* nil)
- (defstruct (bit-buffer (:conc-name nil))
- (buffer-size 0)
- (buffer-data 0))
- (defun take-bit ()
- (with-slots (buffer-size buffer-data) *bit-buffer*
- (unless (plusp buffer-size)
- (error "buffer is empty"))
- (prog1 (ldb (byte 1 (1- buffer-size)) buffer-data)
- (setf buffer-data (ldb (byte (1- buffer-size) 0) buffer-data))
- (decf buffer-size))))
- (defun put-bit (bit)
- (unless (or (= 0 bit)
- (= 1 bit))
- (error "value is not a bit: ~A" bit))
- (with-slots (buffer-size buffer-data) *bit-buffer*
- (setf buffer-data (logior (ash bit buffer-size)
- buffer-data))
- (incf buffer-size)))
- (defun read-bit ()
- (with-slots (buffer-size buffer-data) *bit-buffer*
- (if (plusp buffer-size)
- (take-bit)
- (progn
- (let ((byte (fast-io:fast-read-byte *byte-buffer*)))
- (prog1 (ldb (byte 1 7) byte)
- (setf buffer-data (ldb (byte 7 0) byte))
- (setf buffer-size 7)))))))
- (defun read-bits (count
- &key
- (endian :be)
- (signed nil))
- (let ((unsigned-res
- (ecase endian
- (:be
- (loop
- :repeat count
- :for bit := (read-bit)
- :for res := bit :then (logior (ash res 1) bit)
- :finally
- (return res)))
- (:le
- (loop
- :for i :from 0 :below count
- :for bit := (read-bit)
- :for res := bit :then (logior (ash bit i) res)
- :finally
- (return res))))))
- (if (and signed
- (logbitp (1- count) unsigned-res))
- (- (ldb (byte (1- count) 0) unsigned-res))
- unsigned-res)))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement