diff --git a/src/strings.lisp b/src/strings.lisp index 543434f..0fefdf0 100644 --- a/src/strings.lisp +++ b/src/strings.lisp @@ -141,12 +141,14 @@ that LW/CMU automatically converts strings from c-calls." (let ((size (gensym)) (storage (gensym)) (stored-obj (gensym)) + #+sb-unicode (converted (gensym)) (i (gensym))) `(let ((,stored-obj ,obj)) (etypecase ,stored-obj (null (sb-alien:sap-alien (sb-sys:int-sap 0) (* (sb-alien:unsigned 8)))) (string + #-sb-unicode (let* ((,size (length ,stored-obj)) (,storage (sb-alien:make-alien (sb-alien:unsigned 8) (1+ ,size)))) (setq ,storage (sb-alien:cast ,storage (* (sb-alien:unsigned 8)))) @@ -157,7 +159,20 @@ that LW/CMU automatically converts strings from c-calls." (setf (sb-alien:deref ,storage ,i) (char-code (char ,stored-obj ,i)))) (setf (sb-alien:deref ,storage ,size) 0)) - ,storage))))) + ,storage) + #+sb-unicode + (let* ((,converted (sb-impl::output-to-c-string/utf-8 ,stored-obj)) + (,size (length ,converted)) + (,storage (sb-alien:make-alien (sb-alien:unsigned 8) ,size))) + (setq ,storage (sb-alien:cast ,storage (* (sb-alien:unsigned 8)))) + (locally + (declare (optimize (speed 3) (safety 0))) + (dotimes (,i ,size) + (declare (fixnum ,i)) + (setf (sb-alien:deref ,storage ,i) + (aref ,converted ,i)))) + ,storage) + )))) #+(or openmcl digitool) (let ((stored-obj (gensym))) `(let ((,stored-obj ,obj)) @@ -267,13 +282,18 @@ that LW/CMU automatically converts strings from c-calls." `(new-ptr ,size) ) -(defun foreign-string-length (foreign-string) +(defmacro foreign-string-length (foreign-string) #+allegro `(ff:foreign-strlen ,foreign-string) - #-allegro + #+(and (not allegro) (not sb-unicode)) `(loop with size = 0 - until (char= (deref-array ,foreign-string '(:array :unsigned-char) size) #\Null) - do (incf size) - finally return size)) + until (char= (deref-array ,foreign-string '(:array :unsigned-char) size) #\Null) + do (incf size) + finally (return size)) + #+(and sbcl sb-unicode) + `(loop with size = 0 + until (= (deref-array ,foreign-string '(:array :utf-8) size) 0) + do (incf size) + finally (return size))) (defmacro with-foreign-string ((foreign-string lisp-string) &body body)