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