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