4 ;; doesnt support arrays yet,
5 ;; see (%list-ivars (%objc_getClass "NSConcreteFileHandle"))
8 ;; http://developer.apple.com/documentation/Cocoa/Conceptual/ObjectiveC/Articles/chapter_5_section_7.html
9 (defparameter *type-encodings
*
25 (:unsigned-long-long
"Q")
29 (:long-double
"d") ;; test this on all platforms, unknown on ppc
40 (:unknown
"?" 4))) ;; this size may be implementation specific
42 (defparameter *method-encodings
*
51 (defun-with-types get-method-types
((class class-name
:objc-class
)
52 (selector selector-name
:objc-selector
)
53 &optional instance-method
)
54 (let ((method (funcall (if instance-method
#'%class_getInstanceMethod
#'%class_getClassMethod
)
56 (if (cffi:null-pointer-p method
)
57 (error "Class \"~a\" does not have the ~:[class~;instance~] method \"~a\""
58 (if (cffi:null-pointer-p class
) "<NULL>" class-name
)
59 instance-method selector-name
)
60 (values (cffi:foreign-slot-value method
'objc_method
'method_types
)
63 (defun encode-struct (struct)
65 (apply #'concatenate
'string
66 (second struct
) "=" (mapcar #'encode-type
(cddr struct
)))))
68 (defun encode-type (type)
69 (let ((encoding (assoc type
*type-encodings
*)))
70 (cond ((eq type
:void
) (second encoding
))
71 ((and (listp type
) (eq (first type
) :struct
)) (encode-struct type
))
72 (t (values (string (second encoding
))
74 (cffi:foreign-type-size type
)))))))
76 (defun encode-method-type (return-type parameters
)
77 (apply #'concatenate
'string
78 (encode-type return-type
) "@:" (mapcar #'encode-type parameters
)))
81 (defun decode-type (type-string)
82 (if (char= #\^
(elt type-string
0)) :pointer
83 (first (find type-string
*type-encodings
* :key
#'second
:test
#'string
=))))
85 (defun decode-struct-from-method-type (stream)
88 (do ((char (read-char stream
) (read-char stream
)))
92 (when (char= (peek-char nil stream
) #\")
94 (loop while
(char/= #\" (read-char stream
))))
96 (labels ((read-until-end ()
97 (do ((char (read-char stream
) (read-char stream
)))
101 (when (char= #\
{ char
)
105 (coerce (reverse name
) 'string
)
106 (decode-method-types (coerce (reverse types
) 'string
)))))
108 (defun decode-method-types (method-types)
110 (with-input-from-string (s method-types
)
111 (do* ((token (read-char s
) (read-char s nil
:eof
)))
113 (let ((objc-name (find (string token
) *type-encodings
*
114 :key
#'second
:test
#'string
=)))
116 (push (first objc-name
) types
))
118 (push :pointer types
)
121 (push (decode-struct-from-method-type s
) types
))
123 (loop while
(char/= #\" (read-char s
))))))))