1 ;;;; -*- Mode: Lisp; Syntax: ANSI-Common-Lisp; indent-tabs-mode: nil -*-
3 ;;; --- Device common functions.
6 (in-package :io.zeta-streams
)
8 ;;;-------------------------------------------------------------------------
10 ;;;-------------------------------------------------------------------------
13 ((handle :initarg
:handle
14 :accessor device-handle
)
15 (readable :initarg
:readable
16 :accessor device-readablep
)
17 (writeable :initarg
:writeable
18 :accessor device-writeablep
)
19 (seekable :initarg
:seekable
20 :accessor device-seekablep
)))
22 (defclass direct-device
(device) ())
24 (defclass memory-buffer-device
(direct-device) ())
27 ;;;-------------------------------------------------------------------------
28 ;;; Relinquish I/O resources
29 ;;;-------------------------------------------------------------------------
31 (defgeneric relinquish
(device &rest args
&key abort
))
34 ;;;-------------------------------------------------------------------------
36 ;;;-------------------------------------------------------------------------
38 (defgeneric device-read
(device vector
&key start end timeout
))
40 (defgeneric device-write
(device vector
&key start end timeout
))
42 (defgeneric device-position
(device))
44 (defgeneric (setf device-position
) (position device
&optional from
))
46 (defgeneric device-length
(device))
48 (defgeneric (setf device-length
) (length device
))
50 (defgeneric device-poll
(device direction
&optional timeout
))
52 ;;; Internal functions
54 (defgeneric device-open
(device &rest initargs
))
56 (defgeneric device-read
/non-blocking
(device vector start end
))
58 (defgeneric device-read
/timeout
(device vector start end timeout
))
60 (defgeneric device-write
/non-blocking
(device vector start end
))
62 (defgeneric device-write
/timeout
(device vector start end timeout
))
65 ;;;-------------------------------------------------------------------------
67 ;;;-------------------------------------------------------------------------
69 (defmacro with-device
((name) &body body
)
70 `(let ((*device
* ,name
))
71 (declare (special *device
*))
75 ;;;-------------------------------------------------------------------------
76 ;;; Default no-op methods
77 ;;;-------------------------------------------------------------------------
79 (defmethod relinquish (device &key abort
)
80 (declare (ignore device abort
)))
82 (defmethod device-position ((device device
))
83 ;; FIXME: signal proper condition
84 (error "Device not seekable: ~S" device
))
86 (defmethod (setf device-position
) (position (device device
) &optional from
)
87 (declare (ignore position from
))
88 ;; FIXME: signal proper condition
89 (error "Device not seekable: ~S" device
))
91 (defmethod device-length ((device device
))
92 ;; FIXME: signal proper condition
93 (error "Device not seekable: ~S" device
))
95 (defmethod (setf device-length
) (length (device device
))
96 (declare (ignore length
))
97 ;; FIXME: signal proper condition
98 (error "Device not seekable: ~S" device
))
101 ;;;-------------------------------------------------------------------------
102 ;;; Default DEVICE-READ
103 ;;;-------------------------------------------------------------------------
105 (defmethod device-read :around
((device device
) vector
&key
106 (start 0) end timeout
)
107 (check-bounds vector start end
)
108 (when (= start end
) (return* 0))
109 (call-next-method device vector
:start start
:end end
:timeout timeout
))
111 (defmethod device-read ((device device
) vector
&key start end timeout
)
112 (if (and timeout
(zerop timeout
))
113 (device-read/non-blocking device vector start end
)
114 (device-read/timeout device vector start end timeout
)))
117 ;;;-------------------------------------------------------------------------
118 ;;; Default DEVICE-WRITE
119 ;;;-------------------------------------------------------------------------
121 (defmethod device-write :around
((device device
) vector
&key
122 (start 0) end timeout
)
123 (check-bounds vector start end
)
124 (when (= start end
) (return* 0))
125 (call-next-method device vector
:start start
:end end
:timeout timeout
))
127 (defmethod device-write ((device device
) vector
&key start end timeout
)
128 (if (and timeout
(zerop timeout
))
129 (device-write/non-blocking device vector start end
)
130 (device-write/timeout device vector start end timeout
)))