Version 2.0.0 for new API foreign encoding functions
[uffi.git] / src / i18n.lisp
index 1d6a485145458426532d4d568d079cd9bcf5d5cd..2de8234f9f659cdef49de31608428368801caca9 100644 (file)
@@ -58,8 +58,7 @@ encoding.")
 (defun lookup-foreign-encoding (normalized)
   (cdr (assoc normalized *foreign-encoding-mapping* :test 'eql)))
 
-(defmacro string-to-octets (str &key (encoding *default-foreign-encoding*))
-  "Converts a Lisp string to a vector of octets."
+(defmacro string-to-octets (str &key encoding null-terminate)
   (declare (ignorable encoding))
   #-(or allegro lispworks openmcl sbcl)
   (map-into (make-array (length str) :element-type '(unsigned-byte 8))
@@ -68,35 +67,48 @@ encoding.")
   #+allegro
   (let ((fe (gensym "FE-"))
         (ife (gensym "IFE-"))
-        (s (gensym "STR-")))
-    `(let* ((,fe ,encoding)
+        (s (gensym "STR-"))
+        (nt (gensym "NT-")))
+    `(let* ((,fe (or ,encoding *default-foreign-encoding*))
             (,ife (when ,fe (lookup-foreign-encoding ,fe)))
-            (,s ,str))
+            (,s ,str)
+            (,nt ,null-terminate))
        (values
         (if ,ife
-            (excl:string-to-octets ,s :external-format ,ife :null-terminate nil)
-            (excl:string-to-octets ,s :null-terminate nil)))))
+            (excl:string-to-octets ,s :external-format ,ife :null-terminate ,nt)
+            (excl:string-to-octets ,s :null-terminate ,nt)))))
 
   #+(or lispworks openmcl)
   ;; simply reading each char-code from the LENGTH of string handles multibyte characters
   ;; just fine in testing LW 6.0 and CCL 1.4
-  (map-into (make-array (length str) :element-type '(unsigned-byte 8))
-            #'char-code str)
+  (let ((len (gensym "LEN-"))
+        (out (gensym "OUT-")))
+    `(let ((,len (length ,str)))
+       (if (,null-terminate)
+           (progn
+             (let ((,out (map-into (make-array (1+ ,len) :element-type '(unsigned-byte 8))
+                                   #'char-code ,str)))
+               (setf (char ,out ,len) 0)
+               ,out))
+           (map-into (make-array len :element-type '(unsigned-byte 8))
+                     #'char-code str))))
 
   #+sbcl
   (let ((fe (gensym "FE-"))
         (ife (gensym "IFE-"))
-        (s (gensym "STR-")))
-    `(let* ((,fe ,encoding)
+        (s (gensym "STR-"))
+        (nt (gensym "NT-")))
+    `(let* ((,fe (or ,encoding *default-foreign-encoding*))
             (,ife (when ,fe (lookup-foreign-encoding ,fe)))
-            (,s ,str))
+            (,s ,str)
+            (,nt ,null-terminate))
        (if ,ife
-           (sb-ext:string-to-octets ,s :external-format ,ife)
-           (sb-ext:string-to-octets ,s))))
+           (sb-ext:string-to-octets ,s :external-format ,ife :null-terminate ,nt)
+           (sb-ext:string-to-octets ,s :null-terminate ,nt))))
 
 )
 
-(defmacro octets-to-string (octets &key (encoding *default-foreign-encoding*))
+(defmacro octets-to-string (octets &key encoding)
   "Converts a vector of octets to a Lisp string."
   (declare (ignorable encoding))
   #-(or allegro lispworks openmcl sbcl)
@@ -110,7 +122,7 @@ encoding.")
   (let ((fe (gensym "FE-"))
         (ife (gensym "IFE-"))
         (oct (gensym "OCTETS-")))
-    `(let* ((,fe ,encoding)
+    `(let* ((,fe (or ,encoding *default-foreign-encoding*))
             (,ife (when ,fe (lookup-foreign-encoding ,fe)))
             (,oct ,octets))
        (values
@@ -130,7 +142,7 @@ encoding.")
   (let ((fe (gensym "FE-"))
         (ife (gensym "IFE-"))
         (oct (gensym "OCTETS-")))
-    `(let* ((,fe ,encoding)
+    `(let* ((,fe (or ,encoding *default-foreign-encoding*))
             (,ife (when ,fe (lookup-foreign-encoding ,fe)))
             (,oct ,octets))
        (if ,ife
@@ -139,7 +151,7 @@ encoding.")
 
 )
 
-(defun foreign-encoded-octet-count (str &key (encoding *default-foreign-encoding*))
+(defun foreign-encoded-octet-count (str &key encoding)
   "Returns the octets required to represent the string when passed to a ~
 foreign function."
   (declare (ignorable encoding))
@@ -148,7 +160,8 @@ foreign function."
   ;; with external-format
 
   #+(or (and allegro ics) (and sbcl sb-unicode) (and clisp i18n))
-  (length (string-to-octets str :encoding encoding))
+  (length (string-to-octets str :encoding
+                            (or encoding *default-foreign-encoding*)))
 
   #-(or (and allegro ics) (and sbcl sb-unicode) (and clisp i18n))
   (length str)