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