chiark / gitweb /
Made toggle reference depend on glib2.8
[clg] / glib / glib.lisp
... / ...
CommitLineData
1;; Common Lisp bindings for GTK+ 2.x
2;; Copyright 1999-2005 Espen S. Johnsen <espen@users.sf.net>
3;;
4;; Permission is hereby granted, free of charge, to any person obtaining
5;; a copy of this software and associated documentation files (the
6;; "Software"), to deal in the Software without restriction, including
7;; without limitation the rights to use, copy, modify, merge, publish,
8;; distribute, sublicense, and/or sell copies of the Software, and to
9;; permit persons to whom the Software is furnished to do so, subject to
10;; the following conditions:
11;;
12;; The above copyright notice and this permission notice shall be
13;; included in all copies or substantial portions of the Software.
14;;
15;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16;; EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17;; MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18;; IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19;; CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20;; TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21;; SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
23;; $Id: glib.lisp,v 1.31 2005-04-24 13:27:20 espen Exp $
24
25
26(in-package "GLIB")
27
28(use-prefix "g")
29
30
31;;;; Memory management
32
33(defbinding (allocate-memory "g_malloc0") () pointer
34 (size unsigned-long))
35
36(defbinding (reallocate-memory "g_realloc") () pointer
37 (address pointer)
38 (size unsigned-long))
39
40(defbinding (deallocate-memory "g_free") () nil
41 (address pointer))
42;; (defun deallocate-memory (address)
43;; (declare (ignore address)))
44
45(defun copy-memory (from length &optional (to (allocate-memory length)))
46 #+cmu(system-area-copy from 0 to 0 (* 8 length))
47 #+sbcl(system-area-ub8-copy from 0 to 0 length)
48 to)
49
50
51;;;; User data mechanism
52
53(internal *user-data* *user-data-count*)
54
55(defvar *user-data* (make-hash-table))
56(defvar *user-data-count* 0)
57
58(defun register-user-data (object &optional destroy-function)
59 (check-type destroy-function (or null symbol function))
60 (incf *user-data-count*)
61 (setf
62 (gethash *user-data-count* *user-data*)
63 (cons object destroy-function))
64 *user-data-count*)
65
66(defun find-user-data (id)
67 (check-type id fixnum)
68 (multiple-value-bind (user-data p) (gethash id *user-data*)
69 (values (car user-data) p)))
70
71(defun user-data-exists-p (id)
72 (nth-value 1 (find-user-data id)))
73
74(defun update-user-data (id object)
75 (check-type id fixnum)
76 (multiple-value-bind (user-data exists-p) (gethash id *user-data*)
77 (cond
78 ((not exists-p) (error "User data id ~A does not exist" id))
79 (t
80 (when (cdr user-data)
81 (funcall (cdr user-data) (car user-data)))
82 (setf (car user-data) object)))))
83
84(defun destroy-user-data (id)
85 (check-type id fixnum)
86 (let ((user-data (gethash id *user-data*)))
87 (when (cdr user-data)
88 (funcall (cdr user-data) (car user-data))))
89 (remhash id *user-data*))
90
91
92;;;; Quarks
93
94(deftype quark () 'unsigned)
95
96(defbinding %quark-from-string () quark
97 (string string))
98
99(defun quark-intern (object)
100 (etypecase object
101 (quark object)
102 (string (%quark-from-string object))
103 (symbol (%quark-from-string (format nil "clg-~A:~A"
104 (package-name (symbol-package object))
105 object)))))
106
107(defbinding quark-to-string () (copy-of string)
108 (quark quark))
109
110
111;;;; Linked list (GList)
112
113(deftype glist (type)
114 `(or (null (cons ,type list))))
115
116(defbinding (%glist-append "g_list_append") () pointer
117 (glist pointer)
118 (nil null))
119
120(defun make-glist (type list)
121 (loop
122 with writer = (writer-function type)
123 for element in list
124 as glist = (%glist-append (or glist (make-pointer 0)))
125 do (funcall writer element glist)
126 finally (return glist)))
127
128(defun glist-next (glist)
129 (unless (null-pointer-p glist)
130 (sap-ref-sap glist +size-of-pointer+)))
131
132;; Also used for gslists
133(defun map-glist (seqtype function glist element-type)
134 (let ((reader (reader-function element-type)))
135 (case seqtype
136 ((nil)
137 (loop
138 as tmp = glist then (glist-next tmp)
139 until (null-pointer-p tmp)
140 do (funcall function (funcall reader tmp))))
141 (list
142 (loop
143 as tmp = glist then (glist-next tmp)
144 until (null-pointer-p tmp)
145 collect (funcall function (funcall reader tmp))))
146 (t
147 (coerce
148 (loop
149 as tmp = glist then (glist-next tmp)
150 until (null-pointer-p tmp)
151 collect (funcall function (funcall reader tmp)))
152 seqtype)))))
153
154(defbinding (glist-free "g_list_free") () nil
155 (glist pointer))
156
157(defun destroy-glist (glist element-type)
158 (loop
159 with destroy = (destroy-function element-type)
160 as tmp = glist then (glist-next tmp)
161 until (null-pointer-p tmp)
162 do (funcall destroy tmp 0))
163 (glist-free glist))
164
165(defmethod alien-type ((type (eql 'glist)) &rest args)
166 (declare (ignore type args))
167 (alien-type 'pointer))
168
169(defmethod size-of ((type (eql 'glist)) &rest args)
170 (declare (ignore type args))
171 (size-of 'pointer))
172
173(defmethod to-alien-form (list (type (eql 'glist)) &rest args)
174 (declare (ignore type))
175 (destructuring-bind (element-type) args
176 `(make-glist ',element-type ,list)))
177
178(defmethod to-alien-function ((type (eql 'glist)) &rest args)
179 (declare (ignore type))
180 (destructuring-bind (element-type) args
181 #'(lambda (list)
182 (make-glist element-type list))))
183
184(defmethod from-alien-form (glist (type (eql 'glist)) &rest args)
185 (declare (ignore type))
186 (destructuring-bind (element-type) args
187 `(let ((glist ,glist))
188 (unwind-protect
189 (map-glist 'list #'identity glist ',element-type)
190 (destroy-glist glist ',element-type)))))
191
192(defmethod from-alien-function ((type (eql 'glist)) &rest args)
193 (declare (ignore type))
194 (destructuring-bind (element-type) args
195 #'(lambda (glist)
196 (unwind-protect
197 (map-glist 'list #'identity glist element-type)
198 (destroy-glist glist element-type)))))
199
200(defmethod copy-from-alien-form (glist (type (eql 'glist)) &rest args)
201 (declare (ignore type))
202 (destructuring-bind (element-type) args
203 `(map-glist 'list #'identity ,glist ',element-type)))
204
205(defmethod copy-from-alien-function ((type (eql 'glist)) &rest args)
206 (declare (ignore type))
207 (destructuring-bind (element-type) args
208 #'(lambda (glist)
209 (map-glist 'list #'identity glist element-type))))
210
211(defmethod cleanup-form (glist (type (eql 'glist)) &rest args)
212 (declare (ignore type))
213 (destructuring-bind (element-type) args
214 `(destroy-glist ,glist ',element-type)))
215
216(defmethod cleanup-function ((type (eql 'glist)) &rest args)
217 (declare (ignore type))
218 (destructuring-bind (element-type) args
219 #'(lambda (glist)
220 (destroy-glist glist element-type))))
221
222(defmethod writer-function ((type (eql 'glist)) &rest args)
223 (declare (ignore type))
224 (destructuring-bind (element-type) args
225 #'(lambda (list location &optional (offset 0))
226 (setf
227 (sap-ref-sap location offset)
228 (make-glist element-type list)))))
229
230(defmethod reader-function ((type (eql 'glist)) &rest args)
231 (declare (ignore type))
232 (destructuring-bind (element-type) args
233 #'(lambda (location &optional (offset 0))
234 (unless (null-pointer-p (sap-ref-sap location offset))
235 (map-glist 'list #'identity (sap-ref-sap location offset) element-type)))))
236
237(defmethod destroy-function ((type (eql 'glist)) &rest args)
238 (declare (ignore type))
239 (destructuring-bind (element-type) args
240 #'(lambda (location &optional (offset 0))
241 (unless (null-pointer-p (sap-ref-sap location offset))
242 (destroy-glist (sap-ref-sap location offset) element-type)
243 (setf (sap-ref-sap location offset) (make-pointer 0))))))
244
245
246
247;;;; Single linked list (GSList)
248
249(deftype gslist (type) `(or (null (cons ,type list))))
250
251(defbinding (%gslist-prepend "g_slist_prepend") () pointer
252 (gslist pointer)
253 (nil null))
254
255(defun make-gslist (type list)
256 (loop
257 with writer = (writer-function type)
258 for element in (reverse list)
259 as gslist = (%gslist-prepend (or gslist (make-pointer 0)))
260 do (funcall writer element gslist)
261 finally (return gslist)))
262
263(defbinding (gslist-free "g_slist_free") () nil
264 (gslist pointer))
265
266(defun destroy-gslist (gslist element-type)
267 (loop
268 with destroy = (destroy-function element-type)
269 as tmp = gslist then (glist-next tmp)
270 until (null-pointer-p tmp)
271 do (funcall destroy tmp 0))
272 (gslist-free gslist))
273
274(defmethod alien-type ((type (eql 'gslist)) &rest args)
275 (declare (ignore type args))
276 (alien-type 'pointer))
277
278(defmethod size-of ((type (eql 'gslist)) &rest args)
279 (declare (ignore type args))
280 (size-of 'pointer))
281
282(defmethod to-alien-form (list (type (eql 'gslist)) &rest args)
283 (declare (ignore type))
284 (destructuring-bind (element-type) args
285 `(make-sglist ',element-type ,list)))
286
287(defmethod to-alien-function ((type (eql 'gslist)) &rest args)
288 (declare (ignore type))
289 (destructuring-bind (element-type) args
290 #'(lambda (list)
291 (make-gslist element-type list))))
292
293(defmethod from-alien-form (gslist (type (eql 'gslist)) &rest args)
294 (declare (ignore type))
295 (destructuring-bind (element-type) args
296 `(let ((gslist ,gslist))
297 (unwind-protect
298 (map-glist 'list #'identity gslist ',element-type)
299 (destroy-gslist gslist ',element-type)))))
300
301(defmethod from-alien-function ((type (eql 'gslist)) &rest args)
302 (declare (ignore type))
303 (destructuring-bind (element-type) args
304 #'(lambda (gslist)
305 (unwind-protect
306 (map-glist 'list #'identity gslist element-type)
307 (destroy-gslist gslist element-type)))))
308
309(defmethod copy-from-alien-form (gslist (type (eql 'gslist)) &rest args)
310 (declare (ignore type))
311 (destructuring-bind (element-type) args
312 `(map-glist 'list #'identity ,gslist ',element-type)))
313
314(defmethod copy-from-alien-function ((type (eql 'gslist)) &rest args)
315 (declare (ignore type))
316 (destructuring-bind (element-type) args
317 #'(lambda (gslist)
318 (map-glist 'list #'identity gslist element-type))))
319
320(defmethod cleanup-form (gslist (type (eql 'gslist)) &rest args)
321 (declare (ignore type))
322 (destructuring-bind (element-type) args
323 `(destroy-gslist ,gslist ',element-type)))
324
325(defmethod cleanup-function ((type (eql 'gslist)) &rest args)
326 (declare (ignore type))
327 (destructuring-bind (element-type) args
328 #'(lambda (gslist)
329 (destroy-gslist gslist element-type))))
330
331(defmethod writer-function ((type (eql 'gslist)) &rest args)
332 (declare (ignore type))
333 (destructuring-bind (element-type) args
334 #'(lambda (list location &optional (offset 0))
335 (setf
336 (sap-ref-sap location offset)
337 (make-gslist element-type list)))))
338
339(defmethod reader-function ((type (eql 'gslist)) &rest args)
340 (declare (ignore type))
341 (destructuring-bind (element-type) args
342 #'(lambda (location &optional (offset 0))
343 (unless (null-pointer-p (sap-ref-sap location offset))
344 (map-glist 'list #'identity (sap-ref-sap location offset) element-type)))))
345
346(defmethod destroy-function ((type (eql 'gslist)) &rest args)
347 (declare (ignore type))
348 (destructuring-bind (element-type) args
349 #'(lambda (location &optional (offset 0))
350 (unless (null-pointer-p (sap-ref-sap location offset))
351 (destroy-gslist (sap-ref-sap location offset) element-type)
352 (setf (sap-ref-sap location offset) (make-pointer 0))))))
353
354
355;;; Vector
356
357(defun make-c-vector (type length &optional content location)
358 (let* ((size-of-type (size-of type))
359 (location (or location (allocate-memory (* size-of-type length))))
360 (writer (writer-function type)))
361 (etypecase content
362 (vector
363 (loop
364 for element across content
365 for i from 0 below length
366 as offset = 0 then (+ offset size-of-type)
367 do (funcall writer element location offset)))
368 (list
369 (loop
370 for element in content
371 for i from 0 below length
372 as offset = 0 then (+ offset size-of-type)
373 do (funcall writer element location offset))))
374 location))
375
376
377(defun map-c-vector (seqtype function location element-type length)
378 (let ((reader (reader-function element-type))
379 (size-of-element (size-of element-type)))
380 (case seqtype
381 ((nil)
382 (loop
383 for i from 0 below length
384 as offset = 0 then (+ offset size-of-element)
385 do (funcall function (funcall reader location offset))))
386 (list
387 (loop
388 for i from 0 below length
389 as offset = 0 then (+ offset size-of-element)
390 collect (funcall function (funcall reader location offset))))
391 (t
392 (loop
393 with sequence = (make-sequence seqtype length)
394 for i from 0 below length
395 as offset = 0 then (+ offset size-of-element)
396 do (setf
397 (elt sequence i)
398 (funcall function (funcall reader location offset)))
399 finally (return sequence))))))
400
401
402(defun destroy-c-vector (location element-type length)
403 (loop
404 with destroy = (destroy-function element-type)
405 with element-size = (size-of element-type)
406 for i from 0 below length
407 as offset = 0 then (+ offset element-size)
408 do (funcall destroy location offset))
409 (deallocate-memory location))
410
411
412(defmethod alien-type ((type (eql 'vector)) &rest args)
413 (declare (ignore type args))
414 (alien-type 'pointer))
415
416(defmethod size-of ((type (eql 'vector)) &rest args)
417 (declare (ignore type args))
418 (size-of 'pointer))
419
420(defmethod to-alien-form (vector (type (eql 'vector)) &rest args)
421 (declare (ignore type))
422 (destructuring-bind (element-type &optional (length '*)) args
423 (if (eq length '*)
424 `(let* ((vector ,vector)
425 (location (sap+
426 (allocate-memory (+ ,+size-of-int+
427 (* ,(size-of element-type)
428 (length vector))))
429 ,+size-of-int+)))
430 (make-c-vector ',element-type (length vector) vector location)
431 (setf (sap-ref-32 location ,(- +size-of-int+)) (length vector))
432 location)
433 `(make-c-vector ',element-type ,length ,vector))))
434
435(defmethod from-alien-form (c-vector (type (eql 'vector)) &rest args)
436 (declare (ignore type))
437 (destructuring-bind (element-type &optional (length '*)) args
438 (if (eq length '*)
439 (error "Can't use vector of variable size as return type")
440 `(let ((c-vector ,c-vector))
441 (prog1
442 (map-c-vector 'vector #'identity c-vector ',element-type ,length)
443 (destroy-c-vector c-vector ',element-type ,length))))))
444
445(defmethod copy-from-alien-form (c-vector (type (eql 'vector)) &rest args)
446 (declare (ignore type))
447 (destructuring-bind (element-type &optional (length '*)) args
448 (if (eq length '*)
449 (error "Can't use vector of variable size as return type")
450 `(map-c-vector 'vector #'identity ,c-vector ',element-type ,length))))
451
452(defmethod copy-from-alien-function ((type (eql 'vector)) &rest args)
453 (declare (ignore type))
454 (destructuring-bind (element-type &optional (length '*)) args
455 (if (eq length '*)
456 (error "Can't use vector of variable size as return type")
457 #'(lambda (c-vector)
458 (map-c-vector 'vector #'identity c-vector element-type length)))))
459
460(defmethod cleanup-form (location (type (eql 'vector)) &rest args)
461 (declare (ignore type))
462 (destructuring-bind (element-type &optional (length '*)) args
463 `(let* ((location ,location)
464 (length ,(if (eq length '*)
465 `(sap-ref-32 location ,(- +size-of-int+))
466 length)))
467 (loop
468 with destroy = (destroy-function ',element-type)
469 for i from 0 below length
470 as offset = 0 then (+ offset ,(size-of element-type))
471 do (funcall destroy location offset))
472 (deallocate-memory ,(if (eq length '*)
473 `(sap+ location ,(- +size-of-int+))
474 'location)))))
475
476(defmethod writer-function ((type (eql 'vector)) &rest args)
477 (declare (ignore type))
478 (destructuring-bind (element-type &optional (length '*)) args
479 #'(lambda (vector location &optional (offset 0))
480 (setf
481 (sap-ref-sap location offset)
482 (make-c-vector element-type length vector)))))
483
484(defmethod reader-function ((type (eql 'vector)) &rest args)
485 (declare (ignore type))
486 (destructuring-bind (element-type &optional (length '*)) args
487 (if (eq length '*)
488 (error "Can't create reader function for vector of variable size")
489 #'(lambda (location &optional (offset 0))
490 (unless (null-pointer-p (sap-ref-sap location offset))
491 (map-c-vector 'vector #'identity (sap-ref-sap location offset)
492 element-type length))))))
493
494(defmethod destroy-function ((type (eql 'vector)) &rest args)
495 (declare (ignore type))
496 (destructuring-bind (element-type &optional (length '*)) args
497 (if (eq length '*)
498 (error "Can't create destroy function for vector of variable size")
499 #'(lambda (location &optional (offset 0))
500 (unless (null-pointer-p (sap-ref-sap location offset))
501 (destroy-c-vector
502 (sap-ref-sap location offset) element-type length)
503 (setf (sap-ref-sap location offset) (make-pointer 0)))))))
504
505
506;;;; Null terminated vector
507
508(defun make-0-vector (type content &optional location)
509 (let* ((size-of-type (size-of type))
510 (location (or
511 location
512 (allocate-memory (* size-of-type (1+ (length content))))))
513 (writer (writer-function type)))
514 (etypecase content
515 (vector
516 (loop
517 for element across content
518 as offset = 0 then (+ offset size-of-type)
519 do (funcall writer element location offset)
520 finally (setf (sap-ref-sap location offset) (make-pointer 0))))
521 (list
522 (loop
523 for element in content
524 as offset = 0 then (+ offset size-of-type)
525 do (funcall writer element location offset)
526 finally (setf (sap-ref-sap location (+ offset size-of-type)) (make-pointer 0)))))
527 location))
528
529
530(defun map-0-vector (seqtype function location element-type)
531 (let ((reader (reader-function element-type))
532 (size-of-element (size-of element-type)))
533 (case seqtype
534 ((nil)
535 (loop
536 as offset = 0 then (+ offset size-of-element)
537 until (null-pointer-p (sap-ref-sap location offset))
538 do (funcall function (funcall reader location offset))))
539 (list
540 (loop
541 as offset = 0 then (+ offset size-of-element)
542 until (null-pointer-p (sap-ref-sap location offset))
543 collect (funcall function (funcall reader location offset))))
544 (t
545 (coerce
546 (loop
547 as offset = 0 then (+ offset size-of-element)
548 until (null-pointer-p (sap-ref-sap location offset))
549 collect (funcall function (funcall reader location offset)))
550 seqtype)))))
551
552
553(defun destroy-0-vector (location element-type)
554 (loop
555 with destroy = (destroy-function element-type)
556 with element-size = (size-of element-type)
557 as offset = 0 then (+ offset element-size)
558 until (null-pointer-p (sap-ref-sap location offset))
559 do (funcall destroy location offset))
560 (deallocate-memory location))
561
562(deftype null-terminated-vector (element-type) `(vector ,element-type))
563
564(defmethod alien-type ((type (eql 'null-terminated-vector)) &rest args)
565 (declare (ignore type args))
566 (alien-type 'pointer))
567
568(defmethod size-of ((type (eql 'null-terminated-vector)) &rest args)
569 (declare (ignore type args))
570 (size-of 'pointer))
571
572(defmethod to-alien-form (vector (type (eql 'null-terminated-vector)) &rest args)
573 (declare (ignore type))
574 (destructuring-bind (element-type) args
575 `(make-0-vector ',element-type ,vector)))
576
577(defmethod from-alien-form (c-vector (type (eql 'null-terminated-vector)) &rest args)
578 (declare (ignore type))
579 (destructuring-bind (element-type) args
580 `(let ((c-vector ,c-vector))
581 (prog1
582 (map-0-vector 'vector #'identity c-vector ',element-type)
583 (destroy-0-vector c-vector ',element-type)))))
584
585(defmethod copy-from-alien-form (c-vector (type (eql 'null-terminated-vector)) &rest args)
586 (declare (ignore type))
587 (destructuring-bind (element-type) args
588 `(map-0-vector 'vector #'identity ,c-vector ',element-type)))
589
590(defmethod cleanup-form (location (type (eql 'null-terminated-vector)) &rest args)
591 (declare (ignore type))
592 (destructuring-bind (element-type) args
593 `(destroy-0-vector ,location ',element-type)))
594
595(defmethod writer-function ((type (eql 'null-terminated-vector)) &rest args)
596 (declare (ignore type))
597 (destructuring-bind (element-type) args
598 (unless (eq (alien-type element-type) (alien-type 'pointer))
599 (error "Elements in null-terminated vectors need to be of pointer types"))
600 #'(lambda (vector location &optional (offset 0))
601 (setf
602 (sap-ref-sap location offset)
603 (make-0-vector element-type vector)))))
604
605(defmethod reader-function ((type (eql 'null-terminated-vector)) &rest args)
606 (declare (ignore type))
607 (destructuring-bind (element-type) args
608 (unless (eq (alien-type element-type) (alien-type 'pointer))
609 (error "Elements in null-terminated vectors need to be of pointer types"))
610 #'(lambda (location &optional (offset 0))
611 (unless (null-pointer-p (sap-ref-sap location offset))
612 (map-0-vector 'vector #'identity (sap-ref-sap location offset)
613 element-type)))))
614
615(defmethod destroy-function ((type (eql 'null-terminated-vector)) &rest args)
616 (declare (ignore type))
617 (destructuring-bind (element-type) args
618 (unless (eq (alien-type element-type) (alien-type 'pointer))
619 (error "Elements in null-terminated vectors need to be of pointer types"))
620 #'(lambda (location &optional (offset 0))
621 (unless (null-pointer-p (sap-ref-sap location offset))
622 (destroy-0-vector
623 (sap-ref-sap location offset) element-type)
624 (setf (sap-ref-sap location offset) (make-pointer 0))))))
625
626(defmethod unbound-value ((type (eql 'null-terminated-vector)) &rest args)
627 (declare (ignore type args))
628 (values t nil))
629
630
631;;; Counted vector
632
633(defun make-counted-vector (type content)
634 (let* ((size-of-type (size-of type))
635 (length (length content))
636 (location
637 (allocate-memory (+ +size-of-int+ (* size-of-type length)))))
638 (setf (sap-ref-32 location 0) length)
639 (make-c-vector type length content (sap+ location +size-of-int+))))
640
641(defun map-counted-vector (seqtype function location element-type)
642 (let ((length (sap-ref-32 location 0)))
643 (map-c-vector
644 seqtype function (sap+ location +size-of-int+)
645 element-type length)))
646
647(defun destroy-counted-vector (location element-type)
648 (loop
649 with destroy = (destroy-function element-type)
650 with element-size = (size-of element-type)
651 for i from 0 below (sap-ref-32 location 0)
652 as offset = +size-of-int+ then (+ offset element-size)
653 do (funcall destroy location offset))
654 (deallocate-memory location))
655
656
657(deftype counted-vector (element-type) `(vector ,element-type))
658
659(defmethod alien-type ((type (eql 'counted-vector)) &rest args)
660 (declare (ignore type args))
661 (alien-type 'pointer))
662
663(defmethod size-of ((type (eql 'counted-vector)) &rest args)
664 (declare (ignore type args))
665 (size-of 'pointer))
666
667(defmethod to-alien-form (vector (type (eql 'counted-vector)) &rest args)
668 (declare (ignore type))
669 (destructuring-bind (element-type) args
670 `(make-counted-vector ',element-type ,vector)))
671
672(defmethod from-alien-form (c-vector (type (eql 'counted-vector)) &rest args)
673 (declare (ignore type))
674 (destructuring-bind (element-type) args
675 `(let ((c-vector ,c-vector))
676 (prog1
677 (map-counted-vector 'vector #'identity c-vector ',element-type)
678 (destroy-counted-vector c-vector ',element-type)))))
679
680(defmethod copy-from-alien-form (c-vector (type (eql 'counted-vector)) &rest args)
681 (declare (ignore type))
682 (destructuring-bind (element-type) args
683 `(map-counted-vector 'vector #'identity ,c-vector ',element-type)))
684
685(defmethod copy-from-alien-function ((type (eql 'counted-vector)) &rest args)
686 (declare (ignore type))
687 (destructuring-bind (element-type) args
688 #'(lambda (c-vector)
689 (map-counted-vector 'vector #'identity c-vector element-type))))
690
691(defmethod cleanup-form (location (type (eql 'counted-vector)) &rest args)
692 (declare (ignore type))
693 (destructuring-bind (element-type) args
694 `(destroy-counted-vector ,location ',element-type)))
695
696(defmethod writer-function ((type (eql 'counted-vector)) &rest args)
697 (declare (ignore type))
698 (destructuring-bind (element-type) args
699 #'(lambda (vector location &optional (offset 0))
700 (setf
701 (sap-ref-sap location offset)
702 (make-counted-vector element-type vector)))))
703
704(defmethod reader-function ((type (eql 'counted-vector)) &rest args)
705 (declare (ignore type))
706 (destructuring-bind (element-type) args
707 #'(lambda (location &optional (offset 0))
708 (unless (null-pointer-p (sap-ref-sap location offset))
709 (map-counted-vector 'vector #'identity
710 (sap-ref-sap location offset) element-type)))))
711
712(defmethod destroy-function ((type (eql 'counted-vector)) &rest args)
713 (declare (ignore type))
714 (destructuring-bind (element-type) args
715 #'(lambda (location &optional (offset 0))
716 (unless (null-pointer-p (sap-ref-sap location offset))
717 (destroy-counted-vector
718 (sap-ref-sap location offset) element-type)
719 (setf (sap-ref-sap location offset) (make-pointer 0))))))