Initial import.
This commit is contained in:
commit
6f1edcb56b
|
@ -0,0 +1,19 @@
|
||||||
|
Copyright (c) 2015 Kyle Isom <kyle@metacircular.net>
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
|
@ -0,0 +1,26 @@
|
||||||
|
#:BINARY
|
||||||
|
|
||||||
|
These are various utilities I wrote to read and write integers from
|
||||||
|
binary streams while working on a common lisp interface to the 9P
|
||||||
|
protocol. The following sets of functions are provided:
|
||||||
|
|
||||||
|
- read-{u32,u16,u8}: read unsigned 32-, 16-, and 8-bit integers
|
||||||
|
from a stream.
|
||||||
|
- write-{u32,u16,u8}: write unsigned 32-, 16-, and 8-bit integers
|
||||||
|
from a stream.
|
||||||
|
- read-{i32,i16,i8}: read signed 32-, 16-, and 8-bit integers
|
||||||
|
from a stream.
|
||||||
|
- write-{i32,i16,u8}: write signed 32-, 16-, and 8-bit integers
|
||||||
|
from a stream.
|
||||||
|
|
||||||
|
- octets: read binary data from a stream
|
||||||
|
- {int,uint}-from-bytes: read a signed or unsigned integer from
|
||||||
|
a byte array.
|
||||||
|
- {int,uint}-to-bytes: produce a byte array from a signed or
|
||||||
|
unsigned integer.
|
||||||
|
|
||||||
|
Most of these functions take an endian specifier. Valid endians are
|
||||||
|
:little for little endian (the default) and :big for big endian.
|
||||||
|
|
||||||
|
|
||||||
|
kyle@metacircular.net
|
|
@ -0,0 +1,10 @@
|
||||||
|
;;;; binary.asd
|
||||||
|
|
||||||
|
(asdf:defsystem #:binary
|
||||||
|
:description "Describe binary here"
|
||||||
|
:author "Kyle Isom <kyle@metacircular.net>"
|
||||||
|
:license "MIT License"
|
||||||
|
:serial t
|
||||||
|
:components ((:file "package")
|
||||||
|
(:file "binary")))
|
||||||
|
|
|
@ -0,0 +1,129 @@
|
||||||
|
;;;; binary.lisp
|
||||||
|
|
||||||
|
(in-package #:binary)
|
||||||
|
|
||||||
|
;;; "binary" goes here. Hacks and glory await!
|
||||||
|
|
||||||
|
|
||||||
|
(defconstant U32 4)
|
||||||
|
(defconstant I32 4)
|
||||||
|
(defconstant U16 2)
|
||||||
|
(defconstant I16 2)
|
||||||
|
(defconstant U8 1)
|
||||||
|
(defconstant I8 1)
|
||||||
|
|
||||||
|
(defun octets (stream length)
|
||||||
|
"Read length bytes from the stream."
|
||||||
|
(let ((bin (make-array length :element-type '(unsigned-byte 8))))
|
||||||
|
(read-sequence bin stream)
|
||||||
|
bin))
|
||||||
|
|
||||||
|
(defun uint-from-bytes (bin &key (endian :little))
|
||||||
|
"Produce an unsigned integer from the binary array input."
|
||||||
|
(let ((bin (cond
|
||||||
|
((eql endian :little) bin)
|
||||||
|
((eql endian :big) (reverse bin))
|
||||||
|
(t (error "Invalid endian specification."))))
|
||||||
|
(n 0))
|
||||||
|
(dotimes (i (length bin))
|
||||||
|
(setf n (+ n (ash (aref bin i) (* i 8)))))
|
||||||
|
n))
|
||||||
|
|
||||||
|
(defun uint-to-bytes (n size &key (endian :little))
|
||||||
|
"Produce a binary array of size bytes from the unsigned integer
|
||||||
|
provided."
|
||||||
|
(let ((bin (make-array size :element-type '(unsigned-byte 8))))
|
||||||
|
(dotimes (i size)
|
||||||
|
(setf (aref bin i)
|
||||||
|
(logand 255 (ash n (- 0 (* i 8))))))
|
||||||
|
(cond
|
||||||
|
((eql endian :little) bin)
|
||||||
|
((eql endian :big) (nreverse bin))
|
||||||
|
(t (error "Invalid endian specification.")))))
|
||||||
|
|
||||||
|
(defun read-uint (stream size &key (endian :little))
|
||||||
|
(uint-from-bytes (octets stream size) :endian endian))
|
||||||
|
|
||||||
|
(defun write-uint (stream n size &key (endian :little))
|
||||||
|
(write-sequence (uint-to-bytes n size :endian endian) stream))
|
||||||
|
|
||||||
|
(defmacro define-unsigned-reader (const-name)
|
||||||
|
(let ((docstring
|
||||||
|
(format nil
|
||||||
|
"Read an unsigned ~A-bit integer from a stream."
|
||||||
|
(subseq (format nil "~A" const-name) 1))))
|
||||||
|
`(defun ,(intern (format nil "READ-~A" const-name))
|
||||||
|
(stream &key (endian :little))
|
||||||
|
,docstring
|
||||||
|
(read-uint stream ,const-name :endian endian))))
|
||||||
|
|
||||||
|
(defmacro define-unsigned-writer (const-name)
|
||||||
|
(let ((docstring
|
||||||
|
(format nil
|
||||||
|
"Write an unsigned ~A-bit integer to a stream."
|
||||||
|
(subseq (format nil "~A" const-name) 1))))
|
||||||
|
`(defun ,(intern (format nil "WRITE-~A" const-name))
|
||||||
|
(stream n &key (endian :little))
|
||||||
|
,docstring
|
||||||
|
(write-uint stream n ,const-name :endian endian))))
|
||||||
|
|
||||||
|
(defmacro defunsigned (const-name)
|
||||||
|
`(progn
|
||||||
|
(define-unsigned-reader ,const-name)
|
||||||
|
(define-unsigned-writer ,const-name)))
|
||||||
|
|
||||||
|
(defunsigned U32)
|
||||||
|
(defunsigned U16)
|
||||||
|
(defunsigned U8)
|
||||||
|
|
||||||
|
(defun twos-complement (n size)
|
||||||
|
(if (zerop (logand (ash 1 (* (- size 1) 8)) n))
|
||||||
|
n
|
||||||
|
(- n (ash 1 (* size 8)))))
|
||||||
|
|
||||||
|
(defun int-from-bytes (bin &key (endian :little))
|
||||||
|
"Produce a signed integer from the binary array input."
|
||||||
|
(twos-complement (uint-from-bytes bin :endian endian)
|
||||||
|
(length bin)))
|
||||||
|
|
||||||
|
(defun int-to-bytes (n size &key (endian :little))
|
||||||
|
"Produce a binary array of size bytes from the provided signed
|
||||||
|
integer."
|
||||||
|
(uint-to-bytes (twos-complement n size) size :endian endian))
|
||||||
|
|
||||||
|
(defun read-int (stream size &key (endian :little))
|
||||||
|
(int-from-bytes (octets stream size)
|
||||||
|
:endian endian))
|
||||||
|
|
||||||
|
(defun write-int (stream n size &key (endian :little))
|
||||||
|
(write-sequence (int-to-bytes n size :endian endian)
|
||||||
|
stream))
|
||||||
|
|
||||||
|
(defmacro define-signed-reader (const-name)
|
||||||
|
(let ((docstring
|
||||||
|
(format nil
|
||||||
|
"Read a signed ~A-bit integer from a stream."
|
||||||
|
(subseq (format nil "~A" const-name) 1))))
|
||||||
|
`(defun ,(intern (format nil "READ-~A" const-name))
|
||||||
|
(stream &key (endian :little))
|
||||||
|
,docstring
|
||||||
|
(read-int stream ,const-name :endian endian))))
|
||||||
|
|
||||||
|
(defmacro define-signed-writer (const-name)
|
||||||
|
(let ((docstring
|
||||||
|
(format nil
|
||||||
|
"Write a signed ~A-bit integer to a stream."
|
||||||
|
(subseq (format nil "~A" const-name) 1))))
|
||||||
|
`(defun ,(intern (format nil "WRITE-~A" const-name))
|
||||||
|
(stream n &key (endian :little))
|
||||||
|
,docstring
|
||||||
|
(write-int stream n ,const-name :endian endian))))
|
||||||
|
|
||||||
|
(defmacro defsigned (const-name)
|
||||||
|
`(progn
|
||||||
|
(define-signed-reader ,const-name)
|
||||||
|
(define-signed-writer ,const-name)))
|
||||||
|
|
||||||
|
(defsigned I32)
|
||||||
|
(defsigned I16)
|
||||||
|
(defsigned I8)
|
Loading…
Reference in New Issue