1 ;;;; -*- Mode: Lisp; Syntax: ANSI-Common-Lisp; indent-tabs-mode: nil -*-
6 (in-package :io.zeta-streams
)
8 (declaim (optimize speed
))
10 ;;;-------------------------------------------------------------------------
12 ;;;-------------------------------------------------------------------------
14 (define-constant +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-empty-p (iobuf)
46 (declare (type iobuf iobuf
))
47 (zerop (iobuf-available-octets iobuf
)))
49 (defun iobuf-full-p (iobuf)
50 (declare (type iobuf iobuf
))
54 (defun iobuf-reset (iobuf)
55 (declare (type iobuf iobuf
))
56 (setf (iobuf-start iobuf
) 0
59 (defun iobuf-next-data-zone (iobuf)
60 (declare (type iobuf iobuf
))
61 (values (iobuf-data iobuf
)
65 (defun iobuf-next-empty-zone (iobuf)
66 (declare (type iobuf iobuf
))
67 (values (iobuf-data iobuf
)
72 ;;;-------------------------------------------------------------------------
73 ;;; UNSAFE functions which *DO NOT* check boundaries
74 ;;; that must be done by their callers
75 ;;;-------------------------------------------------------------------------
77 (defun bref (iobuf index
)
78 (declare (type iobuf iobuf
)
79 (type iobuf-index index
))
80 (aref (iobuf-data iobuf
) index
))
82 (defun (setf bref
) (octet iobuf index
)
83 (declare (type ub8 octet
)
85 (type iobuf-index index
))
86 (setf (aref (iobuf-data iobuf
) index
) octet
))
88 (defun iobuf-pop-octet (iobuf)
89 (declare (type iobuf iobuf
))
90 (let ((start (iobuf-start iobuf
)))
91 (prog1 (bref iobuf start
)
92 (setf (iobuf-start iobuf
) (1+ start
)))))
94 (defun iobuf-push-octet (iobuf octet
)
95 (declare (type iobuf iobuf
)
97 (let ((end (iobuf-end iobuf
)))
98 (prog1 (setf (bref iobuf end
) octet
)
99 (setf (iobuf-end iobuf
) (1+ end
)))))
101 (defun replace-ub8sv->ub8sv
(destination source start1 end1 start2 end2
)
102 (declare (type ub8-simple-vector destination source
)
103 (type iobuf-index start1 start2 end1 end2
))
104 (let ((nbytes (min (- end1 start1
)
106 (replace destination source
107 :start1 start1
:end1 end1
108 :start2 start2
:end2 end2
)
111 (defun replace-ub8sv->ub8cv
(destination source start1 end1 start2 end2
)
112 (declare (type ub8-simple-vector source
)
113 (type ub8-complex-vector destination
)
114 (type iobuf-index start1 start2 end1 end2
))
115 (let ((nbytes (min (- end1 start1
)
117 (replace destination source
118 :start1 start1
:end1 end1
119 :start2 start2
:end2 end2
)
122 (defun replace-ub8cv->ub8sv
(destination source start1 end1 start2 end2
)
123 (declare (type ub8-complex-vector source
)
124 (type ub8-simple-vector destination
)
125 (type iobuf-index start1 start2 end1 end2
))
126 (let ((nbytes (min (- end1 start1
)
128 (replace destination source
129 :start1 start1
:end1 end1
130 :start2 start2
:end2 end2
)
133 (defun iobuf->vector
(iobuf vector start end
)
134 (declare (type iobuf iobuf
)
135 (type ub8-vector vector
)
136 (type iobuf-index start end
))
137 (when (iobuf-empty-p iobuf
)
139 (multiple-value-bind (iobuf-data data-start data-end
)
140 (iobuf-next-data-zone iobuf
)
141 (declare (type iobuf-index data-start data-end
))
145 (replace-ub8sv->ub8sv vector iobuf-data
147 data-start data-end
))
149 (replace-ub8sv->ub8cv vector iobuf-data
151 data-start data-end
)))))
152 (setf (iobuf-start iobuf
) (+ data-start
(the iobuf-index nbytes
)))
155 (defun vector->iobuf
(iobuf vector start end
)
156 (declare (type iobuf iobuf
)
157 (type ub8-vector vector
)
158 (type iobuf-index start end
))
159 (when (iobuf-empty-p iobuf
)
161 (multiple-value-bind (iobuf-data data-start data-end
)
162 (iobuf-next-empty-zone iobuf
)
163 (declare (type iobuf-index data-start data-end
))
167 (replace-ub8sv->ub8sv iobuf-data vector
171 (replace-ub8cv->ub8sv iobuf-data vector
174 (setf (iobuf-end iobuf
) (+ data-start
(the iobuf-index nbytes
)))