From: Thibault Langlois
Subject: sbcl, zlib and uffi
Date: 
Message-ID: <1182276349.851395.59380@q75g2000hsh.googlegroups.com>
Hello c.l.l,

I am having some troubles using the zlib package with sbcl.
My goal is to be able to use the uffi-based zlib that is part of cl-
pdf with imago. The imago package has its own pure lisp zlib package
that happens to be slower than the uffi based one.

With cmucl, there is no problem, I redefine imago's zlib:compress so
that it calls pdf:compress-string:
 (defun zlib:compress (bytes btype)
  (declare (ignore btype))
  (string-to-bytes (pdf::compress-string (bytes-to-string bytes))))

bytes-to-string and string-to-bytes convert a vector of bytes into a
string and back. With cmucl there is no problem doing that because
char-code-limit is 256.

SBCL supports unicode so the problem is different. Using apropos I
found two functions in sbcl that I thought would be usefull: sb-
ext:octets-to-string  and sb-ext:string-to-octets. Unfortunately I get
an error from sb-ext:string-to-octets :  The value -34825096 is not of
type (UNSIGNED-BYTE 8).
So sb-ext:string-to-octets cannot deal with the unicode chars that
pdf::compress-string returns.

I tried to digg a little deeper and went to see how pdf::compress-
string works.  The interesting part is how the result of the foreign
call is transformed by uffi::convert-from-foreign-string that calls
uffi::sbcl-naturalize-cstring:
#+(and sbcl sb-unicode)
(defun sbcl-naturalize-cstring (sap &key length (null-terminated-p t))
  (declare (type sb-sys:system-area-pointer sap)
	   (type (or null fixnum) length))
  (locally
   (declare (optimize (speed 3) (safety 0)))
   (cond
    (null-terminated-p
     (let ((casted (sb-alien:cast (sb-alien:sap-alien sap (* char))
				  #+sb-unicode sb-alien:utf8-string
				  #-sb-unicode sb-alien:c-string)))
       (if length
	   (copy-seq (subseq casted 0 length))
	 (copy-seq casted))))
    (t
     (let ((result (make-string length)))
       ;; this will not work in sb-unicode
       (funcall *system-copy-fn* sap 0 result +system-copy-offset+
		(* length +system-copy-multiplier+))
       result)))))

where unfortunately there is a comment that says that it will not work
if sbcl has the sb-unicode feature.
Maybe I could solve the problem by recompiling sbcl without unicode
support but it would be better to have both unicode and uffi working.
So I think that maybe it would be possible to convert the alien data
into a vector of (unsigned-byte 8) instead of a string. Unfortunately
I know nothing about ffi stuff.

Any comment/advice/pointer is welcome.

Thibault