1 ;; -*- Mode: Lisp; Syntax: ANSI-Common-Lisp -*-
3 ;; Copyright (C) 2006, 2007 Stelian Ionescu
5 ;; This code is free software; you can redistribute it and/or
6 ;; modify it under the terms of the version 2.1 of
7 ;; the GNU Lesser General Public License as published by
8 ;; the Free Software Foundation, as clarified by the
9 ;; preamble found here:
10 ;; http://opensource.franz.com/preamble.html
12 ;; This program is distributed in the hope that it will be useful,
13 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
14 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 ;; GNU General Public License for more details.
17 ;; You should have received a copy of the GNU Lesser General
18 ;; Public License along with this library; if not, write to the
19 ;; Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
20 ;; Boston, MA 02110-1301, USA
22 (in-package :net.sockets
)
27 (defclass dynamic-output-buffer
()
28 ((sequence :initform nil
:reader buffer-sequence
)
29 (length :initform
0 :reader buffer-length
)
30 (size :initarg
:size
:reader buffer-size
))
31 (:default-initargs
:size
+dns-datagram-size
+))
33 (defmethod initialize-instance :after
((buffer dynamic-output-buffer
)
35 (setf (slot-value buffer
'sequence
)
36 (make-array size
:element-type
'octet
37 :adjustable t
:fill-pointer
0)))
39 (defun ub16-to-vector (value)
40 (vector (ldb (byte 8 8) value
)
41 (ldb (byte 8 0) value
)))
43 (defun ub32-to-vector (value)
44 (vector (ldb (byte 8 32) value
)
45 (ldb (byte 8 16) value
)
46 (ldb (byte 8 8) value
)
47 (ldb (byte 8 0) value
)))
49 (defgeneric write-vector
(buffer vector
))
51 (defmethod write-vector :before
((buffer dynamic-output-buffer
)
53 (with-slots (sequence length size
) buffer
54 (let ((vector-length (length vector
)))
55 (when (< size
(+ length vector-length
))
56 (let ((newsize (+ size vector-length
50)))
57 (setf sequence
(adjust-array sequence newsize
))
58 (setf size newsize
))))))
60 (defmethod write-vector ((buffer dynamic-output-buffer
)
62 (with-slots (sequence length
) buffer
63 (let ((vector-length (length vector
)))
64 (incf (fill-pointer sequence
) vector-length
)
65 (replace sequence vector
:start1 length
)
66 (incf length vector-length
)))
69 (defgeneric write-unsigned-8
(buffer vector
))
70 (defmethod write-unsigned-8 ((buffer dynamic-output-buffer
)
72 (write-vector buffer
(vector value
)))
74 (defgeneric write-unsigned-16
(buffer vector
))
75 (defmethod write-unsigned-16 ((buffer dynamic-output-buffer
)
77 (write-vector buffer
(ub16-to-vector value
)))
79 (defgeneric write-unsigned-32
(buffer vector
))
80 (defmethod write-unsigned-32 ((buffer dynamic-output-buffer
)
82 (write-vector buffer
(ub32-to-vector value
)))
84 (defmacro with-output-buffer
(var &body body
)
85 `(let ((,var
(make-instance 'dynamic-output-buffer
)))
90 (defclass dynamic-input-buffer
()
91 ((sequence :initform nil
:initarg
:sequence
:reader buffer-sequence
)
92 (position :initform
0 :reader buffer-position
)
93 (size :reader buffer-size
)))
95 (defmethod initialize-instance :after
((buffer dynamic-input-buffer
) &key size
)
96 (with-slots (sequence (seq-size size
)) buffer
97 (setf seq-size
(or size
(length sequence
)))
100 (setf sequence
(make-array 0 :element-type
'octet
:adjustable t
101 :initial-contents sequence
)))
102 ((not (and (adjustable-array-p sequence
)
103 (typep sequence
'(vector octet
))))
104 (setf sequence
(make-array seq-size
105 :element-type
'octet
:adjustable t
106 :displaced-to sequence
))))))
108 (define-condition input-buffer-error
(error) ())
110 (define-condition input-buffer-scarcity
(input-buffer-error)
111 ((bytes-requested :initarg
:requested
:reader bytes-requested
)
112 (bytes-remaining :initarg
:remaining
:reader bytes-remaining
))
113 (:documentation
"Signals that an INPUT-BUFFER contains less unread bytes than requested."))
115 (define-condition input-buffer-eof
(input-buffer-scarcity) ()
116 (:documentation
"Signals that an INPUT-BUFFER contains no more unread bytes."))
118 (define-condition input-buffer-index-out-of-bounds
(input-buffer-error) ()
119 (:documentation
"Signals that BUFFER-SEEK on an INPUT-BUFFER was passed an invalid offset."))
121 (defgeneric buffer-seek
(buffer offset
))
122 (defmethod buffer-seek ((buffer dynamic-input-buffer
) offset
)
123 (check-type offset unsigned-byte
"a non-negative value")
124 (with-slots (sequence size position
) buffer
125 (if (> offset
(1- size
))
126 (error 'input-buffer-index-out-of-bounds
)
127 (setf position offset
))))
129 (defgeneric buffer-append
(buffer vector
))
130 (defmethod buffer-append ((buffer dynamic-input-buffer
)
132 (with-slots (sequence size
) buffer
133 (when (plusp (length vector
))
135 (newsize (+ (length sequence
)
137 (setf sequence
(adjust-array sequence newsize
))
138 (replace sequence vector
:start1 oldsize
)
139 (setf size newsize
)))))
141 (defgeneric bytes-unread
(buffer))
142 (defmethod bytes-unread ((buffer dynamic-input-buffer
))
143 (with-slots (position size
) buffer
146 (defgeneric check-if-enough-bytes
(buffer length
&key check-all
))
147 (defmethod check-if-enough-bytes ((buffer dynamic-input-buffer
)
148 length
&key
(check-all t
))
149 (let ((bytes-unread (bytes-unread buffer
)))
151 ((and (zerop bytes-unread
)
153 (error 'input-buffer-eof
155 :remaining bytes-unread
))
157 (< bytes-unread length
))
158 (error 'input-buffer-scarcity
160 :remaining bytes-unread
)))
163 (defun read-ub16-from-vector (vector position
)
164 (+ (ash (aref vector position
) 8)
165 (aref vector
(1+ position
))))
167 (defun read-ub32-from-vector (vector position
)
168 (+ (ash (aref vector position
) 24)
169 (ash (aref vector
(1+ position
)) 16)
170 (ash (aref vector
(+ position
2)) 8)
171 (aref vector
(+ position
3))))
173 (defgeneric read-vector
(buffer length
&key read-all
))
174 (defmethod read-vector ((buffer dynamic-input-buffer
)
175 length
&key
(read-all t
))
176 (let* ((bytes-to-read
177 (min (bytes-unread buffer
) length
))
179 (make-array bytes-to-read
:element-type
'octet
)))
180 (check-if-enough-bytes buffer length
:check-all read-all
)
181 (with-slots (sequence position
) buffer
182 (replace newvector sequence
:start2 position
)
183 (incf position bytes-to-read
))
186 (defgeneric read-unsigned-8
(buffer))
187 (defmethod read-unsigned-8 ((buffer dynamic-input-buffer
))
188 (check-if-enough-bytes buffer
1)
189 (with-slots (sequence position
) buffer
191 (aref sequence position
)
194 (defgeneric read-unsigned-16
(buffer))
195 (defmethod read-unsigned-16 ((buffer dynamic-input-buffer
))
196 (check-if-enough-bytes buffer
2)
197 (with-slots (sequence position
) buffer
199 (read-ub16-from-vector sequence position
)
202 (defgeneric read-unsigned-32
(buffer))
203 (defmethod read-unsigned-32 ((buffer dynamic-input-buffer
))
204 (check-if-enough-bytes buffer
4)
205 (with-slots (sequence position
) buffer
207 (read-ub32-from-vector sequence position
)
210 (defmacro with-input-buffer
((var) &body body
)
211 `(let ((,var
(make-instance 'dynamic-input-buffer
)))