More code cleanup.
[iolib.git] / io.streams / zeta / iobuf.lisp
blobe3a5cfe14e7e3d9b93536e9198d50f4469cfc43a
1 ;;;; -*- Mode: Lisp; Syntax: ANSI-Common-Lisp; indent-tabs-mode: nil -*-
2 ;;;
3 ;;; --- I/O buffers.
4 ;;;
6 (in-package :io.zeta-streams)
8 (declaim (optimize speed))
10 ;;;; Foreign Buffers
12 (define-constant +default-iobuf-size+ 4096)
14 ;;; almost 128 MB: large enough for a stream buffer,
15 ;;; but small enough to fit into a fixnum
16 (deftype iobuf-index () '(unsigned-byte 27))
17 (deftype iobuf-length () '(integer 0 #.(expt 2 27)))
19 (deftype iobuf-data-vector () 'ub8-simple-vector)
21 (defparameter *empty-vector* (make-array 0 :element-type 'ub8))
23 (defstruct (iobuf (:constructor %make-iobuf ()))
24 (data *empty-vector* :type iobuf-data-vector)
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)
33 (declare (type (or null iobuf-index) size))
34 (let ((b (%make-iobuf)))
35 (setf (iobuf-data b) (make-iobuf-data-vector (or size +default-iobuf-size+)))
36 (values b)))
38 (defun iobuf-size (iobuf)
39 (declare (type iobuf iobuf))
40 (length (iobuf-data iobuf)))
42 (defun iobuf-available-octets (iobuf)
43 (declare (type iobuf iobuf))
44 (- (iobuf-end iobuf)
45 (iobuf-start iobuf)))
47 (defun iobuf-empty-p (iobuf)
48 (declare (type iobuf iobuf))
49 (= (iobuf-start iobuf)
50 (iobuf-end iobuf)))
52 (defun iobuf-full-p (iobuf)
53 (declare (type iobuf iobuf))
54 (= (iobuf-end iobuf)
55 (iobuf-size iobuf)))
57 (defun iobuf-reset (iobuf)
58 (declare (type iobuf iobuf))
59 (setf (iobuf-start iobuf) 0
60 (iobuf-end iobuf) 0))
62 (defun iobuf-next-data-zone (iobuf)
63 (values (iobuf-data iobuf)
64 (iobuf-start iobuf)
65 (iobuf-end iobuf)))
67 (defun iobuf-next-empty-zone (iobuf)
68 (values (iobuf-data iobuf)
69 (iobuf-end iobuf)
70 (iobuf-size iobuf)))
73 ;;;
74 ;;; UNSAFE functions which *DO NOT* check boundaries
75 ;;; that must be done by their callers
76 ;;;
78 (defun bref (iobuf index)
79 (declare (type iobuf iobuf)
80 (type iobuf-index index))
81 (aref (iobuf-data iobuf) index))
83 (defun (setf bref) (octet iobuf index)
84 (declare (type ub8 octet)
85 (type iobuf iobuf)
86 (type iobuf-index index))
87 (setf (aref (iobuf-data iobuf) index) octet))
89 (defun iobuf-pop-octet (iobuf)
90 (declare (type iobuf iobuf))
91 (let ((start (iobuf-start iobuf)))
92 (prog1 (bref iobuf start)
93 (incf (iobuf-start iobuf)))))
95 (defun iobuf-push-octet (iobuf octet)
96 (declare (type iobuf iobuf)
97 (type ub8 octet))
98 (let ((end (iobuf-end iobuf)))
99 (prog1 (setf (bref iobuf end) octet)
100 (incf (iobuf-end iobuf)))))
102 (defun replace-ub8 (destination source start1 end1 start2 end2)
103 (declare (type ub8-simple-vector destination source)
104 (type iobuf-index start1 start2 end1 end2))
105 (let ((nbytes (min (- end1 start1)
106 (- end2 start2))))
107 (replace destination source
108 :start1 start1 :end1 end1
109 :start2 start2 :end2 end2)
110 (values destination nbytes)))
112 (defun iobuf->vector (iobuf vector start end)
113 (declare (type iobuf iobuf)
114 (type ub8-simple-vector vector)
115 (type iobuf-index start end))
116 (when (iobuf-empty-p iobuf)
117 (iobuf-reset iobuf))
118 (let ((nbytes
119 (nth-value 1 (replace-ub8 vector (iobuf-data iobuf)
120 start end
121 (iobuf-start iobuf)
122 (iobuf-end iobuf)))))
123 (incf (iobuf-start iobuf) nbytes)
124 (values nbytes)))
126 (defun vector->iobuf (iobuf vector start end)
127 (declare (type iobuf iobuf)
128 (type ub8-simple-vector vector)
129 (type iobuf-index start end))
130 (when (iobuf-empty-p iobuf)
131 (iobuf-reset iobuf))
132 (let ((nbytes
133 (nth-value 1 (replace-ub8 (iobuf-data iobuf) vector
134 (iobuf-start iobuf)
135 (iobuf-end iobuf)
136 start end))))
137 (incf (iobuf-end iobuf) nbytes)
138 (values nbytes)))