X-Git-Url: http://git.kpe.io/?p=clsql.git;a=blobdiff_plain;f=db-postgresql-socket%2Fpostgresql-socket-api.lisp;h=879e5bb2a0ede5a358f45e88dad9205676790c87;hp=b12424cce74aa77c547d9a18725b5aee0ec40ffc;hb=906d7a71b35ee1cd6d281623694bc90ced22c339;hpb=d2d49ab13c98bc7a1819a0fd3968268a5567bdc3 diff --git a/db-postgresql-socket/postgresql-socket-api.lisp b/db-postgresql-socket/postgresql-socket-api.lisp index b12424c..879e5bb 100644 --- a/db-postgresql-socket/postgresql-socket-api.lisp +++ b/db-postgresql-socket/postgresql-socket-api.lisp @@ -17,6 +17,15 @@ (in-package #:postgresql-socket) +;; KMR: 2011-06-12 +;; FIXME: The file has code specific to sb-unicode and CCL +;; to assume UTF8 encoded strings. +;; Best fix would be to use the user-specified encoding that is now +;; stored in the database object and use the UFFI 2.x encoding functions +;; to convert strings to/from octet vectors. This allows encoding +;; other than UTF8 and also works on all CL implementations that +;; support wide character strings + (uffi:def-enum pgsql-ftype ((:bytea 17) (:int2 21) @@ -105,13 +114,19 @@ socket interface" (defun send-socket-value-string (socket value) (declare (type stream socket) (type string value)) - #-sb-unicode + #-(or sb-unicode ccl) (loop for char across value - for code = (char-code char) - do (write-byte code socket) - finally (write-byte 0 socket)) + for code = (char-code char) + do (write-byte code socket) + finally (write-byte 0 socket)) + #+ccl + (write-sequence (ccl:encode-string-to-octets + value :external-format :utf-8) socket) + #+ccl + (write-byte 0 socket) #+sb-unicode - (write-sequence (sb-ext:string-to-octets value :null-terminate t) socket) + (write-sequence (sb-ext:string-to-octets value :null-terminate t) + socket) nil) (defun send-socket-value-limstring (socket value limit) @@ -150,24 +165,33 @@ socket interface" (declare (type stream socket)) (read-byte socket)) + (defun read-socket-value-string (socket) (declare (type stream socket)) - #-sb-unicode + #-(or sb-unicode ccl) (with-output-to-string (out) (loop for code = (read-byte socket) - until (zerop code) - do (write-char (code-char code) out))) + until (zerop code) + do (write-char (code-char code) out))) + #+ccl + (let ((bytes (make-array 64 + :element-type '(unsigned-byte 8) + :adjustable t + :fill-pointer 0))) + (loop for code = (read-byte socket) + until (zerop code) + do (vector-push-extend code bytes)) + (ccl:decode-string-from-octets bytes :external-format :utf-8)) #+sb-unicode (let ((bytes (make-array 64 :element-type '(unsigned-byte 8) :adjustable t :fill-pointer 0))) (loop for code = (read-byte socket) - until (zerop code) + until (zerop code) do (vector-push-extend code bytes)) (sb-ext:octets-to-string bytes))) - (defmacro define-message-sender (name (&rest args) &rest clauses) (let ((socket-var (gensym)) (body nil)) @@ -214,11 +238,18 @@ socket interface" (defun read-socket-sequence (stream length &optional (allow-wide t)) (declare (stream stream) (optimize (speed 3) (safety 0))) - #-sb-unicode + #-(or sb-unicode ccl) (let ((result (make-string length))) (dotimes (i length result) (declare (fixnum i)) (setf (char result i) (code-char (read-byte stream))))) + #+ccl + (let ((bytes (make-array length :element-type '(unsigned-byte 8)))) + (declare (type (simple-array (unsigned-byte 8) (*)) bytes)) + (read-sequence bytes stream) + (if allow-wide + (ccl:decode-string-from-octets bytes :external-format :utf-8) + (map 'string #'code-char bytes))) #+sb-unicode (let ((bytes (make-array length :element-type '(unsigned-byte 8)))) (declare (type (simple-array (unsigned-byte 8) (*)) bytes)) @@ -459,7 +490,7 @@ troubles." (defun encrypt-md5 (plaintext salt) (string-downcase (format nil "~{~2,'0X~}" - (coerce (md5sum-sequence (concatenate 'string plaintext salt)) 'list)))) + (coerce (md5sum-string (concatenate 'string plaintext salt)) 'list)))) (defun reopen-postgresql-connection (connection) "Reopen the given PostgreSQL connection. Closes any existing