1 ;;;; -*- Mode: Lisp; Syntax: ANSI-Common-Lisp; indent-tabs-mode: nil -*-
3 ;;; --- Device buffers.
6 (in-package :io.zeta-streams
)
8 ;;;-----------------------------------------------------------------------------
9 ;;; Buffer Classes and Types
10 ;;;-----------------------------------------------------------------------------
12 (defclass buffer
(device)
13 ((single-channel-p :initarg
:single-channel
:accessor single-channel-buffer-p
)
14 (input-buffer :initarg
:input-buffer
:accessor input-buffer-of
)
15 (output-buffer :initarg
:output-buffer
:accessor output-buffer-of
))
16 (:default-initargs
:single-channel nil
))
19 ;;;-----------------------------------------------------------------------------
20 ;;; Buffer Constructors
21 ;;;-----------------------------------------------------------------------------
23 (defmethod initialize-instance :after
((buffer buffer
) &key single-channel
24 input-buffer-size output-buffer-size
)
25 (with-accessors ((input-buffer input-buffer-of
)
26 (output-buffer output-buffer-of
))
29 (check-type input-buffer iobuf
)
30 (setf input-buffer
(make-iobuf input-buffer-size
)))
32 (setf output-buffer input-buffer
)
35 (check-type output-buffer iobuf
)
36 (assert (not (eq input-buffer output-buffer
))))
37 (t (setf output-buffer
(make-iobuf output-buffer-size
)))))))
40 ;;;-----------------------------------------------------------------------------
41 ;;; Buffer Generic Functions
42 ;;;-----------------------------------------------------------------------------
44 (defgeneric buffer-clear-input
(buffer))
46 (defgeneric buffer-clear-output
(buffer))
48 (defgeneric buffer-flush-output
(buffer &optional timeout
))
51 ;;;-----------------------------------------------------------------------------
52 ;;; Buffer DEVICE-READ
53 ;;;-----------------------------------------------------------------------------
55 (defmethod device-read ((device buffer
) buffer start end
&optional timeout
)
56 (when (= start end
) (return-from device-read
0))
57 (read-octets/buffered device buffer start end timeout
))
59 (defun read-octets/buffered
(buffer vector start end timeout
)
60 (declare (type buffer buffer
)
61 (type ub8-simple-vector vector
)
62 (type iobuf-index start end
)
63 (type device-timeout timeout
))
64 (with-accessors ((input-handle input-handle-of
)
65 (input-buffer input-buffer-of
))
68 ((iobuf-empty-p input-buffer
)
69 (let ((nbytes (fill-input-buffer input-handle input-buffer timeout
)))
70 (if (iobuf-empty-p input-buffer
)
71 (if (eql :eof nbytes
) :eof
0)
72 (iobuf->vector input-buffer vector start end
))))
74 (iobuf->vector input-buffer vector start end
)))))
76 (defun fill-input-buffer (input-handle input-buffer timeout
)
77 (multiple-value-bind (data start end
)
78 (iobuf-next-empty-zone input-buffer
)
79 (device-read input-handle data start end timeout
)))
82 ;;;-----------------------------------------------------------------------------
83 ;;; Buffer DEVICE-WRITE
84 ;;;-----------------------------------------------------------------------------
86 (defmethod device-write ((device buffer
) buffer start end
&optional timeout
)
87 (when (= start end
) (return-from device-write
0))
88 (write-octets/buffered device buffer start end timeout
))
90 (defun write-octets/buffered
(buffer vector start end timeout
)
91 (declare (type buffer buffer
)
92 (type ub8-simple-vector vector
)
93 (type iobuf-index start end
)
94 (type device-timeout timeout
))
95 (with-accessors ((output-handle output-handle-of
)
96 (output-buffer output-buffer-of
))
98 (vector->iobuf output-buffer vector start end
)
99 (when (iobuf-full-p output-buffer
)
100 (flush-output-buffer output-handle output-buffer timeout
))))
102 (defun flush-output-buffer (output-handle output-buffer timeout
)
103 (multiple-value-bind (data start end
)
104 (iobuf-next-data-zone output-buffer
)
105 (device-write output-handle data start end timeout
)))
108 ;;;-----------------------------------------------------------------------------
109 ;;; Buffer DEVICE-POSITION
110 ;;;-----------------------------------------------------------------------------
112 (defmethod device-position ((device buffer
))
113 (when-let ((handle-position
114 (device-position (input-handle-of device
))))
115 (+ handle-position
(iobuf-available-octets (input-buffer-of device
)))))
117 (defmethod (setf device-position
) (position (device buffer
) &key
(from :start
))
118 (setf (device-position device
:from from
) position
))
121 ;;;-----------------------------------------------------------------------------
123 ;;;-----------------------------------------------------------------------------
125 (defmethod buffer-clear-input ((buffer buffer
))
126 (iobuf-reset (input-buffer-of buffer
)))
128 (defmethod buffer-clear-output ((buffer buffer
))
129 (iobuf-reset (output-buffer-of buffer
)))
131 (defmethod buffer-flush-output ((buffer buffer
) &optional timeout
)
132 (with-accessors ((output-handle output-handle-of
)
133 (output-buffer output-buffer-of
))
135 (flush-output-buffer output-handle output-buffer timeout
)
136 (iobuf-available-octets output-buffer
)))