Hello!
Current cl-prevalence version does not allow to set specific :external-format when reading or writing files. This is very uncomfortable when current working encoding in application differs from the system locale's one: cl recodes strings on serializing.
Please check this patchset implementing the feature (cumulative with my previous bugfixes for "serialize-sexp-external" and "backup"). Maybe there are some crossplatform-related changes required.
% hg diff diff -r 1edf5cd93bb9 src/prevalence.lisp
--- a/src/prevalence.lisp Sun Jul 26 11:10:13 2009 +0200 +++ b/src/prevalence.lisp Tue Sep 08 22:44:04 2009 +0400 @@ -103,7 +103,11 @@
(transaction-hook ;; type function
:accessor get-transaction-hook
:initarg :transaction-hook
- :initform #'identity))
+ :initform #'identity)
+ (external-format ;; external encoding for file operations + :reader get-external-format
+ :initarg :external-format
+ :initform :utf-8))
(:documentation "Base Prevalence system implementation object"))
(defclass guarded-prevalence-system (prevalence-system)
@@ -156,7 +160,8 @@
(setf transaction-log-stream (open (get-transaction-log system) :direction :output :if-does-not-exist :create - :if-exists :append))))) + :if-exists :append + :external-format (get-external-format system))))))
(defmethod close-open-streams ((system prevalence-system) &key abort) "Close all open stream associated with system (optionally aborting operations in progress)" @@ -242,7 +247,7 @@
:type (get-file-extension system))
snapshot)))
(with-open-file (out snapshot
- :direction :output :if-does-not-exist :create :if-exists :supersede) + :direction :output :if-does-not-exist :create :if-exists :supersede :external-format (get-external-format system))
(funcall (get-serializer system) (get-root-objects system) out (get-serialization-state system))) (when (probe-file transaction-log)
(copy-file transaction-log (merge-pathnames (make-pathname :name (get-transaction-log-filename system timetag) @@ -273,7 +278,7 @@
(clrhash (get-root-objects system))
(close-open-streams system)
(when (probe-file (get-snapshot system))
- (with-open-file (in (get-snapshot system) :direction :input) + (with-open-file (in (get-snapshot system) :direction :input :external-format (get-external-format system)) (setf (get-root-objects system) (funcall (get-deserializer system) in (get-serialization-state system))))) (when (probe-file (get-transaction-log system))
(let ((position 0))
@@ -284,7 +289,7 @@
condition)
(truncate-file (get-transaction-log system) position) (return-from restore))))
- (with-open-file (in (get-transaction-log system) :direction :input) + (with-open-file (in (get-transaction-log system) :direction :input :external-format (get-external-format system))
(loop
(let ((transaction (funcall (get-deserializer system) in (get-serialization-state system)))) (setf position (file-position in))
@@ -310,7 +315,7 @@
(defmethod backup ((system guarded-prevalence-system) &key directory) "Do a backup on a system controlled by a guard"
(funcall (get-guard system)
- #'(lambda () (call-next-method system directory)))) + #'(lambda () (call-next-method system :directory directory))))
(defmethod restore ((system guarded-prevalence-system)) "Restore a system controlled by a guard" @@ -343,8 +348,8 @@ (buffer (make-string 4096)) (index 0) (read-count 0)) - (with-open-file (in file :direction :input) - (with-open-file (out tmp-file :direction :output :if-exists :overwrite :if-does-not-exist :create) + (with-open-file (in file :direction :input :external-format (get-external-format system)) + (with-open-file (out tmp-file :direction :output :if-exists :overwrite :if-does-not-exist :create :external-format (get-external-format system)) (when (> position (file-length in)) (return-from truncate-file)) (loop (when (= index position) (return)) @@ -360,8 +365,8 @@ (defun copy-file (source target) (let ((buffer (make-string 4096)) (read-count 0)) - (with-open-file (in source :direction :input) - (with-open-file (out target :direction :output :if-exists :overwrite :if-does-not-exist :create) + (with-open-file (in source :direction :input :external-format (get-external-format system)) + (with-open-file (out target :direction :output :if-exists :overwrite :if-does-not-exist :create :external-format (get-external-format system)) (loop (setf read-count (read-sequence buffer in)) (write-sequence buffer out :end read-count) diff -r 1edf5cd93bb9 src/serialization/sexp.lisp --- a/src/serialization/sexp.lisp Sun Jul 26 11:10:13 2009 +0200 +++ b/src/serialization/sexp.lisp Tue Sep 08 22:44:04 2009 +0400 @@ -145,8 +145,9 @@ (write-string " . " stream) (serialize-sexp-internal (slot-value object slot) stream serialization-state) (write-string ")" stream)) - serializable-slots)) - (write-string " ) )" stream))))) + serializable-slots) + (write-string " )" stream)) + (write-string " )" stream)))))
;;; objects (defmethod serialize-sexp-internal ((object standard-object) stream serialization-state)
Alexey Voznyuk wrote:
Hello! Current cl-prevalence version does not allow to set specific
:external-format when reading or writing files. This is very uncomfortable when current working encoding in application differs from the system locale's one: cl recodes strings on serializing.
Please check this patchset implementing the feature (cumulative with
my previous bugfixes for "serialize-sexp-external" and "backup"). Maybe there are some crossplatform-related changes required.
[snip]
Here is the copy: http://swizard.info/misc/cl-prevalence.patch
Hi Alexey,
thanks for your proposal. However to integrate this it would be nice to have at least basic test cases.
Can you provide some as part of your patch?
Leslie
Hi Leslie!
Leslie P. Polzer wrote:
Hi Alexey,
thanks for your proposal. However to integrate this it would be nice to have at least basic test cases.
Can you provide some as part of your patch?
Leslie
I'm really sorry about such reply delay. I hope I didn't cause any troubles for you with it.
However you are right about tests, I have a bug in my previous patch :)
Here is the correct version with some tests included: http://swizard.info/misc/cl-prevalence-2.patch
Hi Alexey
I'm really sorry about such reply delay. I hope I didn't cause any
troubles for you with it.
Not at all. I haven't merged your patches yet either. Hope I'll get around to that soon.
Thanks for the update with tests!
Leslie
cl-prevalence-devel@common-lisp.net