1 ;; This file is part of CL-ZMQ.
8 (with-foreign-objects ((major :int
)
11 (%version major minor patch
)
15 (mem-ref patch
:int
))))
19 (defmacro with-context
((context) &body body
)
20 `(let ((,context
(ctx-new)))
23 (ctx-destroy ,context
))))
26 (call-with-error-check
30 (defun ctx-get (context option
)
31 (call-with-error-check
38 (defun ctx-set (context option value
)
39 (call-with-error-check
47 (defun ctx-destroy (context)
48 (call-with-error-check
54 (defun socket (context type
)
55 (call-with-error-check
58 (foreign-enum-value 'socket-types
63 (call-with-error-check
67 (defmacro with-socket
((socket context type
) &body body
)
68 `(let ((,socket
(socket ,context
,type
)))
73 (defun bind (s address
)
74 (with-foreign-string (addr address
)
75 (call-with-error-check #'%bind
(list s addr
))))
77 (defun unbind (s address
)
78 (with-foreign-string (addr address
)
79 (call-with-error-check #'%unbind
(list s addr
))))
81 (defun connect (s address
)
82 (with-foreign-string (addr address
)
83 (call-with-error-check #'%connect
(list s addr
))))
85 (defun disconnect (s address
)
86 (with-foreign-string (addr address
)
87 (call-with-error-check #'%disconnect
(list s addr
))))
89 (defun get-socket-option-value-type (option)
96 :last-endpoint
) :string
)
97 ((:maxmsgsize
) :int64
)
100 (defun getsockopt (socket option
)
101 (let ((return-type (get-socket-option-value-type option
))
102 (option-code (foreign-enum-value 'socket-options option
)))
103 (if (eq return-type
:string
)
104 (with-foreign-objects ((str :char
255)
106 (setf (mem-aref len
'size-t
) (* (foreign-type-size :char
) 255))
107 (%getsockopt socket option-code str len
)
108 (foreign-string-to-lisp str
:count
(mem-aref len
'size-t
)))
109 (with-foreign-objects ((obj return-type
)
111 (setf (mem-aref len
'size-t
) (foreign-type-size return-type
))
112 (%getsockopt socket option-code obj len
)
113 (mem-aref obj return-type
)))))
115 (defun setsockopt (socket option value
)
116 (let ((return-type (get-socket-option-value-type option
))
117 (option-code (foreign-enum-value 'socket-options option
)))
118 (if (eq return-type
:string
)
119 (with-zmq-string ((string len
) value
)
120 (%setsockopt socket option-code string len
))
121 (with-foreign-object (obj return-type
)
122 (setf (mem-aref obj return-type
) value
)
123 (%setsockopt socket option-code obj
124 (foreign-type-size return-type
))))))
128 (defstruct (msg (:constructor %make-msg
))
131 (defun make-msg (&key size data
)
132 (let ((msg (%make-msg
))
133 (raw-msg (foreign-alloc 'c-msg
)))
134 (tg:finalize msg
(lambda ()
136 (foreign-free raw-msg
)))
137 (cond (size (%msg-init-size raw-msg size
))
141 (with-foreign-string (fstr data
)
142 (copy-lisp-string-octets
145 (%msg-init-size raw-msg size
)
146 (%msg-data raw-msg
)))))
147 ((simple-array (unsigned-byte 8))
148 (let ((len (length data
)))
149 (%msg-init-size raw-msg len
)
150 (with-pointer-to-vector-data (ptr data
)
151 (%memcpy
(%msg-data raw-msg
) ptr len
))))
153 (%msg-init-size raw-msg
(length data
))
154 (let ((ptr (%msg-data raw-msg
))
157 (setf (mem-aref ptr
:uchar
(incf i
)) x
))
159 (t (%msg-init raw-msg
)))
160 (setf (msg-raw msg
) raw-msg
)
163 (defun msg-data-as-string (msg)
164 (let ((data (%msg-data
(msg-raw msg
)))
165 (size (%msg-size
(msg-raw msg
))))
166 (unless (zerop (pointer-address data
))
167 (foreign-string-to-lisp data
:count size
))))
169 (defun msg-data-as-array (msg)
170 (let ((data (%msg-data
(msg-raw msg
))))
171 (unless (zerop (pointer-address data
))
172 (let* ((len (msg-size msg
))
173 (arr (#+lispworks sys
:in-static-area
174 #-lispworks cl
:identity
175 (make-array len
:element-type
'(unsigned-byte 8)))))
176 (declare (type (simple-array (unsigned-byte 8)) arr
))
177 (with-pointer-to-vector-data (ptr arr
)
178 (%memcpy ptr data len
))
181 ;;; (xxx)freiksenet: doing zmq operations on closed message sends SBCL to ldb.
182 (defun msg-close (msg)
183 (tg:cancel-finalization msg
)
184 (%msg-close
(msg-raw msg
))
185 (foreign-free (msg-raw msg
)))
187 (defun msg-size (msg)
188 (%msg-size
(msg-raw msg
)))
190 (defun msg-move (dst src
)
191 (%msg-move
(msg-raw dst
) (msg-raw src
)))
193 (defun msg-copy (dst src
)
194 (%msg-copy
(msg-raw dst
) (msg-raw src
)))
196 ;; Sending and recieving
198 (defun send (s data
&rest flags
)
199 (with-foreign-string ((buf len
) data
)
200 (%send s buf
(1- len
)
201 (foreign-bitfield-value 'send-recv-options flags
))))
203 (defun recv (s length
&rest flags
)
204 (with-foreign-string ((buf len
) (make-string length
))
205 (%recv s buf
(1- len
)
206 (foreign-bitfield-value 'send-recv-options flags
))
207 (foreign-string-to-lisp buf
)))
209 (defun msg-send (s msg
&rest flags
)
210 (%msg-send
(msg-raw msg
) s
211 (foreign-bitfield-value 'send-recv-options flags
)))
213 (defun msg-recv (s msg
&rest flags
)
214 (%msg-recv
(msg-raw msg
) s
215 (foreign-bitfield-value 'send-recv-options flags
)))
219 (defun poll (sockets &optional timeout
)
220 (let* ((length (length sockets
))
221 (pollitems (foreign-alloc 'c-pollitem
:count length
)))
223 (apply #'fill-pollitem
224 (mem-aref pollitems
'c-pollitem i
)
226 (let* ((result (call-with-error-check
231 (events (extract-pollitems-events pollitems length
)))
232 (foreign-free pollitems
)
233 (values result events
))))
235 (defun fill-pollitem (pollitem s
&rest flags
)
237 (setf (foreign-slot-value pollitem
'c-pollitem
'fd
)
239 (setf (foreign-slot-value pollitem
'c-pollitem
'socket
)
241 (setf (foreign-slot-value pollitem
'c-pollitem
'events
)
242 (foreign-bitfield-value 'event-types
246 (defun extract-pollitems-events (pollitems length
)
249 (push (extract-pollitem-events (mem-aref pollitems
'c-pollitem i
))
253 (defun extract-pollitem-events (pollitem)
254 (let ((socket (foreign-slot-value pollitem
'c-pollitem
'socket
))
255 (fd (foreign-slot-value pollitem
'c-pollitem
'fd
))
256 (revents (foreign-slot-value pollitem
'c-pollitem
'revents
)))
260 (foreign-bitfield-symbols 'event-types revents
))))