1 ;;;; -*- Mode: Lisp; Syntax: ANSI-Common-Lisp; indent-tabs-mode: nil -*-
6 (in-package :io.zeta-streams
)
8 (declaim (optimize speed
))
10 ;;;-------------------------------------------------------------------------
12 ;;;-------------------------------------------------------------------------
14 (defconstant +default-iobuf-size
+ (* 8 1024))
16 ;; almost 128 MB: large enough for a stream buffer,
17 ;; but small enough to fit into a fixnum
18 (deftype iobuf-index
() '(unsigned-byte 27))
20 (deftype iobuf-data-vector
() 'ub8-simple-vector
)
22 (defstruct (iobuf (:constructor %make-iobuf
(data)))
23 (lock (bt:make-lock
"IObuf lock") :read-only t
)
24 (data nil
:type iobuf-data-vector
:read-only t
)
25 (start 0 :type iobuf-index
)
26 (end 0 :type iobuf-index
))
28 (defun make-iobuf-data-vector (size)
29 (declare (type iobuf-index size
))
30 (make-array size
:element-type
'ub8
:initial-element
0))
32 (defun make-iobuf (&optional
(size +default-iobuf-size
+))
33 (check-type size iobuf-index
)
34 (%make-iobuf
(make-iobuf-data-vector size
)))
36 (defun iobuf-size (iobuf)
37 (declare (type iobuf iobuf
))
38 (the iobuf-index
(length (iobuf-data iobuf
))))
40 (defun iobuf-available-octets (iobuf)
41 (declare (type iobuf iobuf
))
45 (defun iobuf-available-space (iobuf)
46 (declare (type iobuf iobuf
))
50 (defun iobuf-empty-p (iobuf)
51 (declare (type iobuf iobuf
))
52 (zerop (iobuf-available-octets iobuf
)))
54 (defun iobuf-full-p (iobuf)
55 (declare (type iobuf iobuf
))
56 (zerop (iobuf-available-space iobuf
)))
58 (defun iobuf-reset (iobuf)
59 (declare (type iobuf iobuf
))
60 (setf (iobuf-start iobuf
) 0
63 (defun iobuf-next-data-zone (iobuf)
64 (declare (type iobuf iobuf
))
65 (values (iobuf-data iobuf
)
69 (defun iobuf-next-empty-zone (iobuf)
70 (declare (type iobuf iobuf
))
71 (values (iobuf-data iobuf
)
76 ;;;-------------------------------------------------------------------------
77 ;;; UNSAFE functions which *DO NOT* check boundaries
78 ;;; that must be done by their callers
79 ;;;-------------------------------------------------------------------------
81 (defun bref (iobuf index
)
82 (declare (type iobuf iobuf
)
83 (type iobuf-index index
))
84 (aref (iobuf-data iobuf
) index
))
86 (defun (setf bref
) (octet iobuf index
)
87 (declare (type ub8 octet
)
89 (type iobuf-index index
))
90 (setf (aref (iobuf-data iobuf
) index
) octet
))
92 (defun iobuf-pop-octet (iobuf)
93 (declare (type iobuf iobuf
))
94 (let ((start (iobuf-start iobuf
)))
95 (prog1 (bref iobuf start
)
96 (setf (iobuf-start iobuf
) (1+ start
)))))
98 (defun iobuf-push-octet (iobuf octet
)
99 (declare (type iobuf iobuf
)
101 (let ((end (iobuf-end iobuf
)))
102 (prog1 (setf (bref iobuf end
) octet
)
103 (setf (iobuf-end iobuf
) (1+ end
)))))
105 (defun replace-ub8sv->ub8sv
(destination source start1 end1 start2 end2
)
106 (declare (type ub8-simple-vector destination source
)
107 (type iobuf-index start1 start2 end1 end2
))
108 (let ((nbytes (min (- end1 start1
)
110 (replace destination source
111 :start1 start1
:end1 end1
112 :start2 start2
:end2 end2
)
115 (defun replace-ub8sv->ub8cv
(destination source start1 end1 start2 end2
)
116 (declare (type ub8-simple-vector source
)
117 (type ub8-complex-vector destination
)
118 (type iobuf-index start1 start2 end1 end2
))
119 (let ((nbytes (min (- end1 start1
)
121 (replace destination source
122 :start1 start1
:end1 end1
123 :start2 start2
:end2 end2
)
126 (defun replace-ub8cv->ub8sv
(destination source start1 end1 start2 end2
)
127 (declare (type ub8-complex-vector source
)
128 (type ub8-simple-vector destination
)
129 (type iobuf-index start1 start2 end1 end2
))
130 (let ((nbytes (min (- end1 start1
)
132 (replace destination source
133 :start1 start1
:end1 end1
134 :start2 start2
:end2 end2
)
137 (defun iobuf->vector
(iobuf vector start end
)
138 (declare (type iobuf iobuf
)
139 (type ub8-vector vector
)
140 (type iobuf-index start end
))
141 (when (iobuf-empty-p iobuf
)
143 (multiple-value-bind (iobuf-data data-start data-end
)
144 (iobuf-next-data-zone iobuf
)
145 (declare (type iobuf-index data-start data-end
))
149 (replace-ub8sv->ub8sv vector iobuf-data
151 data-start data-end
))
153 (replace-ub8sv->ub8cv vector iobuf-data
155 data-start data-end
)))))
156 (setf (iobuf-start iobuf
) (+ data-start
(the iobuf-index nbytes
)))
159 (defun vector->iobuf
(iobuf vector start end
)
160 (declare (type iobuf iobuf
)
161 (type ub8-vector vector
)
162 (type iobuf-index start end
))
163 (when (iobuf-empty-p iobuf
)
165 (multiple-value-bind (iobuf-data data-start data-end
)
166 (iobuf-next-empty-zone iobuf
)
167 (declare (type iobuf-index data-start data-end
))
171 (replace-ub8sv->ub8sv iobuf-data vector
175 (replace-ub8cv->ub8sv iobuf-data vector
178 (setf (iobuf-end iobuf
) (+ data-start
(the iobuf-index nbytes
)))