Re: Migrating from UFFI to CFFI
Victor <[email protected]> Thu, 17 Oct 2013 13:44:00 +0300
| Newsgroups | gmane.lisp.clsql.general |
|---|---|
| Message-ID | <op.w43hfmrk4lizsz@vanyakin-nb> |
On Thu, 17 Oct 2013 06:27:27 +0300, Kevin Rosenberg <kevin-HJRc7zDS/[email protected]> wrote: > On Oct 16, 2013, at 11:07 AM, Victor <[email protected]> wrote: >> ? (uffi:convert-from-foreign-string (uffi:convert-to-foreign-string "абв")) >> "^Z^Z^Z" >> >> I suspect that the problem is in the uffi:convert-to-foreign-string function. > > Your suspicion may well be right. I look a look at the code and see that > uffi::%convert-to-foreign-string for ccl stores two bytes of zeros after > storing the bytes returned by ccl:encode-string-to-octets. > > On the reverse, uffi:convert-from-foreign-string uses the internal > ccl::%get-utf-8-cstring for decoding :utf-8 encoded foreign strings. > > Perhaps something has changed in the internals of ccl utf-8 representation > since I wrote, tested, and committed that code in Feb 2010. If you see some > useful ideas for an update, please forward them to me and I'll be glad to > commit a fix to work for UFFI to work with the current version of ccl. > Ideally, there may be documented, exported functions for encoding/decoding > internationalized strings in the current version of ccl. Hi Kevin, Indeed, OpenMCL-devel subscribers experienced the same problem. This is a response that I've got from Sergey. The mail from Sergey was Cc-ed to the openmcl-devel mailing list but it did not appear there. I quote him below: | 1) First of all I set ccl:*default-file-character-encoding* and | ccl:*default-socket-character-encoding* to :utf-8 | | 2) And then I patched uffi soures in quicklisp directory See these modifications as a patch attached to this message. | Additionally i've defined encoding for still widely used cp1251, but | I think it's offtopic. I've applied these changes and indeed, Sqlite3 backend now is capable of dealing with UTF-8 encoded strings. However, I also noticed that the problem with UFFI:CONVERT-* functions still remain. Moreover, I've also stuck into the problem that Sergey noticed some time before: http://clozure.com/pipermail/openmcl-devel/2013-April/014220.html it appears that the CCL::%GET-UTF-8-CSTRING function is not a reliable one. I think that if confirmed, this function has some internal problems and should be either fixed or avoided. The two zeroes in the end are a UTF-8 version of the 0 character terminator that ordinary C strings have. CFFI relies on the babel package to get its size, but I guess that this thing is static enough to hard-code it for UTF-8. Thanks! Victor p.s. CP1251 encoding is not defined by the patch but I believe it is a good thing to do in the future. _______________________________________________ CLSQL mailing list [email protected] http://lists.b9.com/cgi-bin/mailman/listinfo/clsql
uffi.patch
(application/octet-stream, 1.2 KB)
diff --git a/src/i18n.lisp b/src/i18n.lisp
index a46b535..36577e5 100644
--- a/src/i18n.lisp
+++ b/src/i18n.lisp
@@ -202,5 +202,6 @@ foreign function."
#-(or (and allegro ics) (and sbcl sb-unicode) (and clisp i18n))
(length str)
-
+ #+(and openmcl openmcl-unicode-strings)
+ (ccl:string-size-in-octets str :external-format (ccl:make-external-format :character-encoding (or encoding *default-foreign-encoding* ccl:*default-file-character-encoding* :utf-8)))
)
diff --git a/src/strings.lisp b/src/strings.lisp
index 430d8ab..1d2f875 100644
--- a/src/strings.lisp
+++ b/src/strings.lisp
@@ -84,7 +84,11 @@ that LW/CMU automatically converts strings from c-calls."
(let ((stored-lisp-string (gensym)))
`(let ((,stored-lisp-string ,lisp-string))
(if (stringp ,stored-lisp-string)
- (ccl:with-cstrs ((,cstring ,stored-lisp-string))
+ (ccl:with-encoded-cstrs
+ (or *default-foreign-encoding*
+ ccl:*default-file-character-encoding*
+ :utf-8)
+ ((,cstring ,stored-lisp-string))
,@body)
(let ((,cstring +null-cstring-pointer+))
,@body))))