[cl-store-cvs] CVS update: cl-store/ChangeLog cl-store/backends.lisp cl-store/circularities.lisp cl-store/cl-store.asd cl-store/default-backend.lisp cl-store/package.lisp cl-store/plumbing.lisp cl-store/tests.lisp cl-store/utils.lisp

Sean Ross sross at common-lisp.net
Fri Feb 11 12:00:38 UTC 2005


Update of /project/cl-store/cvsroot/cl-store
In directory common-lisp.net:/tmp/cvs-serv11891

Modified Files:
	ChangeLog backends.lisp circularities.lisp cl-store.asd 
	default-backend.lisp package.lisp plumbing.lisp tests.lisp 
	utils.lisp 
Log Message:
Changelog 2005-02-11
Date: Fri Feb 11 13:00:31 2005
Author: sross

Index: cl-store/ChangeLog
diff -u cl-store/ChangeLog:1.19 cl-store/ChangeLog:1.20
--- cl-store/ChangeLog:1.19	Thu Feb  3 12:55:13 2005
+++ cl-store/ChangeLog	Fri Feb 11 13:00:30 2005
@@ -1,3 +1,29 @@
+2005-02-11 Sean Ross <sross at common-lisp.net>
+	New Magic Number for cl-store-backend.
+	* default-backend.lisp, acl/custom.lisp, lispworks/custom.lisp
+	* sbcl/custom.lisp, cmucl/custom.lisp:
+	Changed storing of floats to be compatible between implementations
+	while ensuring that NaN floats and friends are still serializable.
+	* backends.lisp, plumbing.lisp:
+	Added concept of backend designators which can be a 
+	symbol (the backend name) or the backend itself. These are 
+	acceptable replacements for a backend object
+	to store, restore and with-backend.
+	Completely changed argument order for generic functions
+	to ensure that backends are the first argument.
+	* ecl/mop.lisp: Added support for ecl.
+	* plumbing.lisp: Removed multiple-value-store (I don't really
+	see the point of it).
+	* backends.lisp: Changed the working of object restoration
+	from functions in a hash-table (restorer-funs of a backend)
+	to generic functions specialized on backend and a symbol,
+	removed find-function-for-type. 
+	* plumbing.lisp: Changed the handling of the stream-type
+	of backends to be any legal type designator since it's 
+	only used when opening files.
+	* backends.lisp: Both defstore-? and defrestore-?
+	can take an optional qualifer argument.
+	
 2005-02-03 Sean Ross <sross at common-lisp.net>
 	* default-backend.lisp: Fixed hash-table restoration,
 	it no longer assumes that the result of hash-table-test
@@ -10,7 +36,7 @@
 	argument-precedence-order from various gf's, added the 
 	start of support for ecl, renamed fix-clisp.lisp file to 
 	mop.lisp, and changed resolving-object and setting 
-	to use delays allowing get-setf-place and *postfix-setter*
+	to use delays allowing get-setf-place and *postfix-setters*
 	to be removed.
 	
 2004-12-02 Sean Ross <sross at common-lisp.net>
@@ -151,7 +177,7 @@
 
 2004-05-21 Sean Ross <sross at common-lisp.net>
 	* store.lisp, fix-clisp.lisp, circularities.lisp, package.lisp, 
-	tests.lisp, utils.lisp, cl-store.asd:
+	* tests.lisp, utils.lisp, cl-store.asd:
 	   Added ability to specify the type code of an object 
 	   when using defstore. Added code to autogenerate the 
 	   accessor methods for CLISP when restoring classes.


Index: cl-store/backends.lisp
diff -u cl-store/backends.lisp:1.7 cl-store/backends.lisp:1.8
--- cl-store/backends.lisp:1.7	Tue Feb  1 09:27:26 2005
+++ cl-store/backends.lisp	Fri Feb 11 13:00:31 2005
@@ -7,8 +7,6 @@
 ;; in default-backend.lisp and xml-backend.lisp
 
 (in-package :cl-store)
-;(declaim (optimize (speed 3) (safety 1) (debug 0)))
-
 
 (defun required-arg (name)
   (error "~A is a required argument" name))
@@ -19,103 +17,93 @@
    (old-magic-numbers :accessor old-magic-numbers :initarg :old-magic-numbers
                       :type integer)
    (stream-type :accessor stream-type :initarg :stream-type :type symbol
-                :initform (required-arg "stream-type"))
-   (restorer-funs :accessor restorer-funs :initform (make-hash-table)
-                  :initarg :restorer-funs :type hash-table))
+                :initform (required-arg "stream-type")))
   (:documentation "Core class which custom backends must extend"))
 
+(deftype backend-designator ()
+  `(or symbol backend))
+
 (defparameter *registered-backends* nil 
   "An assoc list mapping backend-names to the backend objects")
 
-(defun mkstr (&rest args)
-  (with-output-to-string (s)
-    (dolist (x args)
-      (princ x s))))
-
-(defun symbolicate (&rest syms)
-  "Concatenate all symbol names into one big symbol"
-  (values (intern (apply #'mkstr syms))))
+(defun find-backend (name)
+  (declare (type symbol name))
+  "Return backup called NAME or NIL if not found."
+  (cdr (assoc name *registered-backends*)))
+
+(defun backend-designator->backend (designator)
+  (check-type designator backend-designator)
+  (etypecase designator
+    (symbol (or (find-backend designator)
+                (error "~A does not designate a backend." designator)))
+    (backend designator)))
 
-(defun get-store-macro (name class-name)
+(defun get-store-macro (name)
   "Return the defstore-? macro which will be used by a custom backend"
   (let ((macro-name (symbolicate 'defstore- name)))
-    `(defmacro ,macro-name ((var type stream &key qualifier) 
+    `(defmacro ,macro-name ((var type stream &optional qualifier) 
                             &body body)
-      `(defmethod internal-store-object ,@(if qualifier (list qualifier) nil)
-        ((,var ,type) ,stream (backend ,',class-name))
-        ,(format nil "Definition for storing an object of type ~A with ~
-backend ~A" type ',name)
-        , at body))))
+       (with-gensyms (gbackend)
+         `(defmethod internal-store-object ,@(if qualifier (list qualifier) nil)
+            ((,gbackend ,',name) (,var ,type) ,stream)
+            ,(format nil "Definition for storing an object of type ~A with ~
+ backend ~A" type ',name)
+            (declare (ignorable ,gbackend))
+            , at body)))))
 
 (defun get-restore-macro (name)
   "Return the defrestore-? macro which will be used by a custom backend"
   (let ((macro-name (symbolicate 'defrestore- name)))
-    `(defmacro ,macro-name ((type place) &body body)
-      (let ((fn-name (gensym (symbol-name (symbolicate ',name '- type)))))
-        `(flet ((,fn-name (,place) 
-                  , at body))
-          (let* ((backend (find-backend ',',name))
-                 (restorers (restorer-funs backend)))
-            (when (gethash ',type restorers)
-              (warn "Redefining restorer ~A for backend ~(~A~)"
-                    ',type (name backend)))
-            (setf (gethash ',type restorers)
-                  #',fn-name)))))))
-
-(defun real-stream-type (value)
-  (ecase value
-    (char 'character)
-    (binary 'integer)))
+    `(defmacro ,macro-name ((type place &optional qualifier) &body body)
+       (with-gensyms (gbackend gtype)
+         `(defmethod internal-restore-object ,@(if qualifier (list qualifier) nil)
+            ((,gbackend ,',name) (,gtype (eql ',type)) (,place t))
+            (declare (ignorable ,gbackend ,gtype))
+            , at body)))))
 
 (defun register-backend (name class magic-number stream-type old-magic-numbers)
   (declare (type symbol name))
-  (assert (member stream-type '(char binary)))
   (let ((instance (make-instance class
                                  :name name
                                  :magic-number magic-number
                                  :old-magic-numbers old-magic-numbers
-                                 :stream-type (real-stream-type stream-type))))
+                                 :stream-type  stream-type)))
     (if (assoc name *registered-backends*)
-        (cerror "Redefine backend" "Backend is already defined ~A" name)
+        (cerror "Redefine backend" "Backend ~A is already defined." name)
         (push (cons name instance) *registered-backends*))
     instance))
 
-(defun find-backend (name)
-  (declare (type symbol name))
-  "Return backup called NAME or NIL if not found."
-  (cdr (assoc name *registered-backends*)))
 
 (defun get-class-form (name fields extends)
-  `(defclass ,name (,extends)
+  `(defclass ,name ,extends
     ,fields
     (:documentation ,(format nil "Autogenerated cl-store class for backend ~(~A~)."
                              name))))
 
-(defmacro defbackend (name &key (stream-type (required-arg "stream-type"))
-                      (magic-number nil) fields (extends 'backend) 
-                      (old-magic-numbers nil))
+(defmacro defbackend (name &key (stream-type ''(unsigned-byte 8))
+                           (magic-number nil) fields (extends '(backend))
+                           (old-magic-numbers nil))
   "Defines a new backend called NAME. Stream type must be either 'char or 'binary. 
 FIELDS is a list of legal slots for defclass. MAGIC-NUMBER, when supplied, will
 be written down stream as verification and checked on restoration.
 EXTENDS is a class to extend, which must be backend or a class which extends
 backend"
   (assert (symbolp name))
-  (let ((class-name (symbolicate name '-backend)))
-    `(eval-when (:compile-toplevel :load-toplevel :execute)
-       (prog2 
-        ,(get-class-form class-name fields extends)
-          (register-backend ',name ',class-name ,magic-number 
-                            ,stream-type ',old-magic-numbers)
-        ,(get-store-macro name class-name)
-        ,(get-restore-macro name)))))
-
+  `(eval-when (:load-toplevel :execute)
+     (eval-when (:compile-toplevel :load-toplevel :execute)
+       ,(get-class-form name fields extends)
+       ,(get-store-macro name)
+       ,(get-restore-macro name))
+     (register-backend ',name ',name ,magic-number 
+                       ,stream-type ',old-magic-numbers)))
 
 (defmacro with-backend (backend &body body)
   "Run BODY with *default-backend* bound to BACKEND"
-  `(let ((*default-backend* (or (and (typep ,backend 'backend) 
-                                     ,backend)
-                                (error "~A is not a legal backend" 
-                                       ,backend))))
-    , at body))
+  (with-gensyms (gbackend)
+    `(let* ((,gbackend ,backend)
+            (*default-backend* (or (backend-designator->backend ,gbackend)
+                                   (error "~A is not a legal backend" 
+                                          ,gbackend))))
+       , at body)))
 
-;; EOF
\ No newline at end of file
+;; EOF


Index: cl-store/circularities.lisp
diff -u cl-store/circularities.lisp:1.14 cl-store/circularities.lisp:1.15
--- cl-store/circularities.lisp:1.14	Tue Feb  1 09:27:26 2005
+++ cl-store/circularities.lisp	Fri Feb 11 13:00:31 2005
@@ -19,8 +19,6 @@
 ;; programs according to the Hyperspec(notes in EQ).
 
 (in-package :cl-store)
-;(declaim (optimize (speed 3) (safety 1) (debug 1)))
-
 
 (defvar *check-for-circs* t)
 
@@ -42,14 +40,16 @@
   "Resolve the possible referring object retrieved by GET and 
   set it into PLACE. Only usable within a resolving-object form."
   (declare (ignore place get))
-  (error "setting can only be used inside a resolving-object form."))
+  #+ecl nil
+  #-ecl (error "setting can only be used inside a resolving-object form."))
 
 (defmacro setting-hash (getting-key getting-value)
   "Insert the value retrieved by GETTING-VALUE with the key 
   retrieved by GETTING-KEY, resolving possible circularities.
   Only usable within a resolving-object form."
   (declare (ignore getting-key getting-value))
-  (error "setting-hash can only be used inside a resolving-object form."))
+  #+ecl nil
+  #-ecl (error "setting-hash can only be used inside a resolving-object form."))
 
 (defmacro resolving-object ((var create) &body body)
   "Execute body attempting to resolve circularities found in 
@@ -76,8 +76,7 @@
          , at body
          ,var))))
 
-(defstruct referrer 
-  val)
+(defstruct referrer val)
 
 (defun referred-value (referrer hash)
   "Return the value REFERRER is meant to be by looking in HASH."
@@ -100,7 +99,7 @@
   (let ((*stored-counter* 0) 
         (*stored-values* (make-hash-table :test #'eq :size *store-hash-size*))) 
     (store-backend-code backend place)
-    (backend-store-object obj place backend)
+    (backend-store-object backend obj place)
     obj))
 
 (defun seen (obj)
@@ -122,9 +121,9 @@
   "Do we need to check if this object has been stored before?"
   (not (typep obj 'not-circ)))
 
-(defgeneric store-referrer (obj place backend)
+(defgeneric store-referrer (backend obj place)
   (:documentation "Store the number OBJ into PLACE as a referrer for BACKEND.")
-  (:method ((obj t) (place t) (backend resolving-backend))
+  (:method ((backend resolving-backend) (obj t) (place t))
     (store-error  "store-referrer must be specialized for backend ~(~A~)."
                   (name backend))))
 
@@ -136,12 +135,12 @@
            (update-seen obj))
       nil))
 
-(defmethod backend-store-object ((obj t) (place t) (backend resolving-backend))
+(defmethod backend-store-object ((backend resolving-backend) (obj t) (place t))
   "Store object if we have not seen this object before, otherwise retrieve
   the referrer object for it and store that using store-referrer."
   (aif (and *check-for-circs* (get-ref obj))
-       (store-referrer it place backend)
-       (internal-store-object obj place backend)))
+       (store-referrer backend it place)
+       (internal-store-object backend obj place)))
        
 ;; Restoration.
 (declaim (type (or fixnum null) *restore-counter*))
@@ -158,53 +157,36 @@
         (*restored-values* (make-hash-table :test #'eq :size *restore-hash-size*)))
     (check-magic-number backend place)
     (multiple-value-prog1
-      (backend-restore-object place backend)
+      (backend-restore-object backend place)
       (dolist (fn *need-to-fix*)
         (force fn)))))
 
 (defun update-restored (spot val)
   (setf (gethash spot *restored-values*) val))
 
-(defun all-vals (reader place)
-  (declare (type function reader))
-  (multiple-value-list (funcall reader place)))
-
-(defun get-vals (reader place)
-  (declare (type function reader))
-  (mapcar #'new-val (all-vals reader place)))
-
-(defun handle-values (reader place)
+(defun handle-normal (backend reader place)
   (let ((spot (incf *restore-counter*))
-        (vals (get-vals reader place)))
-    (update-restored spot (car vals))
-    (values-list vals)))
-
-(defun call-it (reader place)
-  (funcall (the function reader) place))
-
-(defun handle-normal (reader place)
-  (let ((spot (incf *restore-counter*))
-        (vals (new-val (call-it reader place))))
+        (vals (new-val (internal-restore-object backend reader place))))
     (update-restored spot vals)
     vals))
 
+(defgeneric referrerp (backend reader))
+
 (defun handle-restore (place backend)
-  (multiple-value-bind (reader sym) (find-function-for-type place backend)
-    (declare (type function reader) (type symbol sym))
-    (cond ((eql sym 'values-object)
-           (handle-values reader place))
-          ((eql sym 'referrer)
+  (multiple-value-bind (reader) (get-next-reader backend place)
+    (declare (type symbol reader))
+    (cond ((referrerp backend reader) 
            (incf *restore-counter*)
-           (new-val (call-it reader place)))
-          ((not (int-sym-or-char-p backend sym))
-           (handle-normal reader place))
-          (t (new-val (funcall reader place))))))
+           (new-val (internal-restore-object backend reader place)))
+          ((not (int-sym-or-char-p backend reader))
+           (handle-normal backend reader place))
+          (t (new-val (internal-restore-object backend reader place))))))
 
-(defmethod backend-restore-object ((place stream) (backend resolving-backend))
+(defmethod backend-restore-object ((backend resolving-backend) (place stream))
   "Retrieve a object from PLACE, does housekeeping for circularity fixing."
   (if *check-for-circs*
       (handle-restore place backend)
-      (funcall (the function (find-function-for-type place backend)) place)))
+      (call-next-method)))
 
 (defgeneric int-sym-or-char-p (backend fn)
   (:method ((backend backend) (fn symbol))
@@ -220,5 +202,4 @@
            val)
       val))
 
-
-;; EOF
\ No newline at end of file
+;; EOF


Index: cl-store/cl-store.asd
diff -u cl-store/cl-store.asd:1.18 cl-store/cl-store.asd:1.19
--- cl-store/cl-store.asd:1.18	Thu Feb  3 12:59:12 2005
+++ cl-store/cl-store.asd	Fri Feb 11 13:00:31 2005
@@ -40,7 +40,7 @@
   :name "CL-STORE"
   :author "Sean Ross <sdr at jhb.ucs.co.za>"
   :maintainer "Sean Ross <sdr at jhb.ucs.co.za>"
-  :version "0.4.6"
+  :version "0.4.13"
   :description "Serialization package"
   :long-description "Portable CL Package to serialize data types"
   :licence "MIT"
@@ -65,9 +65,7 @@
   :components ((:file "tests")))
 
 (defmethod perform ((op test-op) (sys (eql (find-system :cl-store-tests))))
-  (or (funcall (find-symbol "RUN-TESTS" "CL-STORE-TESTS")
-               (symbol-value (find-symbol "*CL-STORE-BACKEND*" "CL-STORE")))
-      (error "Test-op Failed.")))
-
+  (funcall (find-symbol "RUN-TESTS" "CL-STORE-TESTS")
+           (find-symbol "CL-STORE" "CL-STORE")))
 
 ;; EOF


Index: cl-store/default-backend.lisp
diff -u cl-store/default-backend.lisp:1.17 cl-store/default-backend.lisp:1.18
--- cl-store/default-backend.lisp:1.17	Thu Feb  3 12:55:13 2005
+++ cl-store/default-backend.lisp	Fri Feb 11 13:00:31 2005
@@ -2,66 +2,68 @@
 ;; See the file LICENCE for licence information.
 
 ;; The cl-store backend. 
-
 (in-package :cl-store)
 
-(eval-when (:compile-toplevel :load-toplevel :execute)
-  (defvar *cl-store-backend*
-    (defbackend cl-store :magic-number 1886611820 
-                :stream-type 'binary
-                :old-magic-numbers (1912923 1886611788 1347635532 
-                                    1884506444 1347643724 1349732684)
-                :extends resolving-backend
-                :fields ((restorers :accessor restorers 
-                                    :initform (make-hash-table :size 100)))))
-  (defun register-code (code name &optional (errorp t))
-    (aif (and (gethash code (restorers *cl-store-backend*)) errorp)
-         (error "Code ~A is already defined for ~A." code name)
-         (setf (gethash code (restorers *cl-store-backend*))
-               name))
-    code))
+(defbackend cl-store :magic-number 1349740876
+            :stream-type '(unsigned-byte 8)
+            :old-magic-numbers (1912923 1886611788 1347635532 1886611820 
+                                        1884506444 1347643724 1349732684)
+            :extends (resolving-backend)
+            :fields ((restorers :accessor restorers 
+                                :initform (make-hash-table :size 100))))
+
+(defun register-code (code name &optional (errorp t))
+  (aif (and (gethash code (restorers (find-backend 'cl-store))) errorp)
+       (error "Code ~A is already defined for ~A." code name)
+       (setf (gethash code (restorers (find-backend 'cl-store)))
+             name))
+  code)
 
 ;;  Type code constants
-(defconstant +referrer-code+ (register-code 1 'referrer nil))
-(defconstant +values-code+ (register-code 2 'values-object nil))
-(defconstant +unicode-string-code+ (register-code 3 'unicode-string nil))
-(defconstant +integer-code+ (register-code 4 'integer nil))
-(defconstant +simple-string-code+ (register-code 5 'simple-string nil))
-(defconstant +float-code+ (register-code 6 'float nil))
-(defconstant +ratio-code+ (register-code 7 'ratio nil))
-(defconstant +character-code+ (register-code 8 'character nil))
-(defconstant +complex-code+ (register-code 9 'complex nil))
-(defconstant +symbol-code+ (register-code 10 'symbol nil))
-(defconstant +cons-code+ (register-code 11 'cons nil))
-(defconstant +pathname-code+ (register-code 12 'pathname nil))
-(defconstant +hash-table-code+ (register-code 13 'hash-table nil))
-(defconstant +standard-object-code+ (register-code 14 'standard-object nil))
-(defconstant +condition-code+ (register-code 15 'condition nil))
-(defconstant +structure-object-code+ (register-code 16 'structure-object nil))
-(defconstant +standard-class-code+ (register-code 17 'standard-class nil))
-(defconstant +built-in-class-code+ (register-code 18 'built-in-class nil))
-(defconstant +array-code+ (register-code 19 'array nil))
-(defconstant +simple-vector-code+ (register-code 20 'simple-vector nil))
-(defconstant +package-code+ (register-code 21 'package nil))
+(defvar +referrer-code+ (register-code 1 'referrer nil))
+;(defvar +values-code+ (register-code 2 'values-object nil))
+(defvar +unicode-string-code+ (register-code 3 'unicode-string nil))
+(defvar +integer-code+ (register-code 4 'integer nil))
+(defvar +simple-string-code+ (register-code 5 'simple-string nil))
+(defvar +float-code+ (register-code 6 'float nil))
+(defvar +ratio-code+ (register-code 7 'ratio nil))
+(defvar +character-code+ (register-code 8 'character nil))
+(defvar +complex-code+ (register-code 9 'complex nil))
+(defvar +symbol-code+ (register-code 10 'symbol nil))
+(defvar +cons-code+ (register-code 11 'cons nil))
+(defvar +pathname-code+ (register-code 12 'pathname nil))
+(defvar +hash-table-code+ (register-code 13 'hash-table nil))
+(defvar +standard-object-code+ (register-code 14 'standard-object nil))
+(defvar +condition-code+ (register-code 15 'condition nil))
+(defvar +structure-object-code+ (register-code 16 'structure-object nil))
+(defvar +standard-class-code+ (register-code 17 'standard-class nil))
+(defvar +built-in-class-code+ (register-code 18 'built-in-class nil))
+(defvar +array-code+ (register-code 19 'array nil))
+(defvar +simple-vector-code+ (register-code 20 'simple-vector nil))
+(defvar +package-code+ (register-code 21 'package nil))
 
 ;; Used by lispworks
-(defconstant +positive-infinity-code+ (register-code 22 'positive-infinity nil))
-(defconstant +negative-infinity-code+ (register-code 23 'negative-infinity nil))
+(defvar +positive-infinity-code+ (register-code 22 'positive-infinity nil))
+(defvar +negative-infinity-code+ (register-code 23 'negative-infinity nil))
 
 ;; new storing for 32 bit ints
-(defconstant +32-bit-integer-code+ (register-code 24 '32-bit-integer nil))
+(defvar +32-bit-integer-code+ (register-code 24 '32-bit-integer nil))
 
 ;; More for lispworks
-(defconstant +float-nan-code+ (register-code 25 'nan-float nil))
+(defvar +float-nan-code+ (register-code 25 'nan-float nil))
 
-(defconstant +function-code+ (register-code 26 'function nil))
-(defconstant +gf-code+ (register-code 27 'generic-function nil))
+(defvar +function-code+ (register-code 26 'function nil))
+(defvar +gf-code+ (register-code 27 'generic-function nil))
 
 ;; Used by SBCL and CMUCL.
-(defconstant +structure-class-code+ (register-code 28 'structure-class nil))
-(defconstant +struct-def-code+ (register-code 29 'struct-def nil))
+(defvar +structure-class-code+ (register-code 28 'structure-class nil))
+(defvar +struct-def-code+ (register-code 29 'struct-def nil))
+
+(defvar +gensym-code+ (register-code 30 'gensym nil))
 
-(defconstant +gensym-code+ (register-code 30 'gensym nil))
+(defvar +positive-double-infinity-code+ (register-code 31 'positive-double-infinity nil))
+(defvar +negative-double-infinity-code+ (register-code 32 'negative-double-infinity nil))
+(defvar +float-double-nan-code+ (register-code 33 'float-double-nan nil))
 
 ;; setups for type code mapping
 (defun output-type-code (code stream)
@@ -71,24 +73,25 @@
 (defun read-type-code (stream)
   (read-byte stream))
 
-(defvar *restorers* (restorers *cl-store-backend*))
+(defmethod referrerp ((backend cl-store) (reader t))
+  (eql reader 'referrer))
+
+(defvar *restorers* (restorers (find-backend 'cl-store)))
+
 ;; get-next-reader needs to return a symbol which will be used by the
 ;; backend to lookup the function that was defined by
 ;; defrestore-cl-store to restore it, or nil if not found. 
-
 (defun lookup-code (code)
   (gethash code *restorers*))
 
-(defmethod get-next-reader ((stream stream) (backend cl-store-backend))
-  (declare (ignore backend))
+(defmethod get-next-reader ((backend cl-store) (stream stream))
   (let ((type-code (read-type-code stream)))
-    (or (lookup-code type-code) ;(gethash type-code *restorers*)
-        (values nil (format nil "Type ~A" type-code)))))
+    (or (lookup-code type-code)
+        (error "Type code ~A is not registered." type-code))))
 
 
 ;; referrer, Required for a resolving backend
-(defmethod store-referrer (ref stream (backend cl-store-backend))
-  (declare (ignore backend))
+(defmethod store-referrer ((backend cl-store) (ref t) (stream t))
   (output-type-code +referrer-code+ stream)
   (dump-int ref stream))
 
@@ -101,8 +104,7 @@
 ;; so we we have a little optimization for it
 
 ;; We need this for circularity stuff.
-(defmethod int-sym-or-char-p ((backend cl-store-backend) (fn symbol))
-  (declare (ignore backend))
+(defmethod int-sym-or-char-p ((backend cl-store) (fn symbol))
   (find fn '(integer character 32-bit-integer symbol)))
 
 (defstore-cl-store (obj integer stream)
@@ -162,29 +164,63 @@
         (- result)
         result)))
 
-;; Floats
-;; SBCL and CMUCL use a different mechanism for dealing
-;; with floats which supports infinities.
-;; Lispworks uses a slightly different version as well
-;; manually handling negative and positive infinity
-;; Allegro uses excl:double-float-to-shorts and friends
-#-(or lispworks cmu sbcl allegro)
+;; Floats (*special-floats* are setup in the custom.lisp files)
+(defvar *special-floats* nil)
+
 (defstore-cl-store (obj float stream)
-  (output-type-code +float-code+ stream)    
-  (multiple-value-bind (significand exponent sign)
-      (integer-decode-float obj)
-    (write-byte (float-type obj) stream)
-    (store-object significand stream)
-    (store-object exponent stream)
-    (store-object sign stream)))
+  (block body
+    (let (significand exponent sign)
+      (handler-bind ((simple-error
+                      #'(lambda (err)
+                          (declare (ignore err))
+                          (awhen (cdr (assoc obj *special-floats*))
+                            (output-type-code it stream)
+                            (return-from body)))))
+        (multiple-value-setq (significand exponent sign)
+          (integer-decode-float obj))
+        (output-type-code +float-code+ stream)
+        (write-byte (float-type obj) stream)
+        (store-object significand stream)
+        (store-object (float-radix obj) stream)
+        (store-object exponent stream)
+        (store-object sign stream)))))
 
-#-(or cmu sbcl allegro)
 (defrestore-cl-store (float stream)
   (float (* (get-float-type (read-byte stream))
             (* (restore-object stream)
-               (expt 2 (restore-object stream)))
+               (expt (restore-object stream)
+                     (restore-object stream)))
             (restore-object stream))))
 
+(defun handle-special-float (code name)
+  (aif (rassoc code *special-floats*)
+       (car it)
+       (store-error "~A Cannot be represented." name)))
+
+(defrestore-cl-store (negative-infinity stream)
+  (handle-special-float +negative-infinity-code+
+                        "Single Float Negative Infinity"))
+
+(defrestore-cl-store (positive-infinity stream)
+  (handle-special-float +positive-infinity-code+
+                        "Single Float Positive Infinity"))
+
+(defrestore-cl-store (nan-float stream)
+   (handle-special-float +float-nan-code+ "Single Float NaN"))
+
+(defrestore-cl-store (negative-double-infinity stream)
+  (handle-special-float +negative-double-infinity-code+
+                        "Double Float Negative Infinity"))
+
+(defrestore-cl-store (positive-double-infinity stream)
+  (handle-special-float +positive-double-infinity-code+
+                        "Double Float Positive Infinity"))
+
+(defrestore-cl-store (float-double-nan stream)
+  (handle-special-float +float-double-nan-code+
+                        "Double Float NaN"))
+
+
 ;; ratio
 (defstore-cl-store (obj ratio stream)
   (output-type-code +ratio-code+ stream)
@@ -231,7 +267,7 @@
 (defrestore-cl-store (gensym stream)
   (make-symbol (restore-object stream)))
 
-  
+
 ;; lists
 (defstore-cl-store (obj cons stream)
   (output-type-code +cons-code+ stream)    
@@ -245,6 +281,7 @@
     (setting (car x) (restore-object stream))
     (setting (cdr x) (restore-object stream))))
 
+
 ;; pathnames
 (defstore-cl-store (obj pathname stream)
   (output-type-code +pathname-code+ stream)
@@ -297,7 +334,6 @@
                             (restore-object stream))))
       hash)))
 
-
 ;; Object and Conditions
 (defun store-type-object (obj stream)
   (let* ((all-slots (remove-if-not (lambda (x)
@@ -321,7 +357,6 @@
   (output-type-code +standard-object-code+ stream)    
   (store-type-object obj stream))
 
-#-lispworks
 (defstore-cl-store (obj condition stream)
   (output-type-code +condition-code+ stream)    
   (store-type-object obj stream))
@@ -339,11 +374,10 @@
               (setting (slot-value obj slot-name) (restore-object stream)))))
     new-instance))
 
-#-lispworks
-(defrestore-cl-store (condition stream)
+(defrestore-cl-store (standard-object stream)
   (restore-type-object stream))
 
-(defrestore-cl-store (standard-object stream)
+(defrestore-cl-store (condition stream)
   (restore-type-object stream))
 
 
@@ -377,12 +411,14 @@
              #+clisp (add-methods-for-class class slots)))))
 
 ;; built in classes
+
 (defstore-cl-store (obj built-in-class stream)
   (output-type-code +built-in-class-code+ stream)
   (store-object (class-name obj) stream))
 
+#-ecl ;; for some reason this doesn't work with ecl
 (defmethod internal-store-object ((obj (eql (find-class 'hash-table))) stream
-                                  (backend cl-store-backend))
+                                  (backend cl-store))
   (output-type-code +built-in-class-code+ stream)
   (store-object 'cl:hash-table stream))
 
@@ -505,17 +541,6 @@
   (find-package (restore-object stream)))
 
 
-;; multiple values
-
-(defstore-cl-store (obj values-object stream)
-  (output-type-code +values-code+ stream)
-  (store-object (vals obj) stream))
-
-(defrestore-cl-store (values-object stream)
-  (apply #'values (restore-object stream)))
-
-
-
 ;; Function storing hack.
 ;; This just stores the function name if we can find it
 ;; or signal a store-error.
@@ -570,6 +595,7 @@
 
 (defrestore-cl-store (generic-function stream)
   (fdefinition (restore-object stream)))
+
 
 (setf *default-backend* (find-backend 'cl-store))
 


Index: cl-store/package.lisp
diff -u cl-store/package.lisp:1.16 cl-store/package.lisp:1.17
--- cl-store/package.lisp:1.16	Tue Feb  1 09:27:26 2005
+++ cl-store/package.lisp	Fri Feb 11 13:00:31 2005
@@ -1,33 +1,28 @@
 ;;; -*- Mode: LISP; Syntax: ANSI-Common-Lisp; Base: 10 -*-
 ;; See the file LICENCE for licence information.
-
+(in-package :cl-store.system)
 (defpackage #:cl-store
   (:use #:cl) 
-  (:export #:backend #:magic-number #:stream-type #:restorer-funs
+  (:export #:backend #:magic-number #:stream-type
            #:restorers #:resolving-backend #:find-backend #:defbackend
            #:*restore-counter* #:*need-to-fix* #:*restored-values*
            #:with-backend #:fix-circularities #:*default-backend*
-           #:*cl-store-backend* #:*current-backend* #:*store-class-slots*
+           #:*current-backend* #:*store-class-slots*
            #:*nuke-existing-classes* #:*store-class-superclasses*
            #:cl-store-error #:store-error #:restore-error #:store
            #:restore #:backend-store #:store-backend-code #:store-object
            #:backend-store-object #:get-class-details #:get-array-values
-           #:restore #:backend-restore
+           #:restore #:backend-restore #:cl-store #:referrerp
            #:check-magic-number #:get-next-reader #:int-sym-or-char-p
            #:restore-object #:backend-restore-object
            #:defstore-cl-store #:defrestore-cl-store #:register-code
            #:output-type-code #:store-referrer #:resolving-object
            #:internal-store-object #:setting #:simple-standard-string
-           #:float-type #:get-float-type #:compute-slots
-           #:slot-definition-allocation #:slot-definition-name
-           #:slot-definition-type #:slot-definition-initargs
-           #:slot-definition-readers #:slot-definition-writers
-           #:class-direct-superclasses #:class-direct-slots
-           #:ensure-class #:make-referrer #:setting-hash
+           #:float-type #:get-float-type #:make-referrer #:setting-hash
            #:multiple-value-store #:*postfix-setters* #:caused-by
            #:store-32-bit #:read-32-bit #:*check-for-circs*
            #:*store-hash-size* #:*restore-hash-size*)
-
+  
   #+sbcl (:import-from #:sb-mop
                        #:generic-function-name
                        #:slot-definition-name


Index: cl-store/plumbing.lisp
diff -u cl-store/plumbing.lisp:1.9 cl-store/plumbing.lisp:1.10
--- cl-store/plumbing.lisp:1.9	Tue Feb  1 09:27:26 2005
+++ cl-store/plumbing.lisp	Fri Feb 11 13:00:31 2005
@@ -53,25 +53,21 @@
   (error 'restore-error :format-string format-string :format-args args))
 
 
-
-
 ;; entry points
 (defun store-to-file (obj place backend)
   (declare (type backend backend))
-  (let* ((backend-type (stream-type backend))
-         (element-type (ecase backend-type
-                         (character 'character)
-                         (integer '(unsigned-byte 8)))))
+  (let* ((element-type (stream-type backend)))
     (with-open-file (s place :element-type element-type
                        :direction :output :if-exists :supersede)
       (backend-store backend s obj))))
 
-(defgeneric store (obj place &optional backend) 
+(defgeneric store (obj place &optional designator) 
   (:documentation "Entry Point for storing objects.")
-  (:method ((obj t) (place t) &optional (backend *default-backend*))
+  (:method ((obj t) (place t) &optional (designator *default-backend*))
     "Store OBJ into Stream PLACE using backend BACKEND."
-    (let ((*current-backend* backend)
-          (*read-eval* nil))
+    (let* ((backend (backend-designator->backend designator))
+           (*current-backend* backend)
+           (*read-eval* nil))
       (handler-bind ((error (lambda (c)
                               (signal (make-condition 'store-error 
                                                       :caused-by c)))))
@@ -104,20 +100,20 @@
 (defun store-object (obj stream &optional (backend *current-backend*))
   "Store OBJ into STREAM. Not meant to be overridden, 
    use backend-store-object instead"
-  (backend-store-object obj stream backend))
+  (backend-store-object backend obj stream))
 
-(defgeneric backend-store-object (obj stream backend)
+(defgeneric backend-store-object (backend obj stream)
   (:documentation
    "Wrapped by store-object, override this to do custom storing 
    (see circularities.lisp for an example).")
-  (:method ((obj t) (stream t) (backend backend))
+  (:method ((backend backend) (obj t) (stream t))
     "The default, just calls internal-store-object."
-    (internal-store-object obj stream backend)))
+    (internal-store-object backend obj stream)))
 
 
-(defgeneric internal-store-object (obj place backend)
+(defgeneric internal-store-object (backend obj place)
   (:documentation "Method which is specialized by defstore-? macros.")
-  (:method ((obj t) (place t) (backend backend))
+  (:method ((backend backend) (obj t) (place t))
     "If call falls back here then OBJ cannot be serialized with BACKEND."
     (store-error "Cannot store objects of type ~A with backend ~(~A~)."
                  (type-of obj) (name backend))))
@@ -127,10 +123,11 @@
   (:documentation 
    "Restore and object FROM PLACE using BACKEND. Not meant to be 
    overridden, use backend-restore instead")
-  (:method (place &optional (backend *default-backend*))
+  (:method (place &optional (designator *default-backend*))
     "Entry point for restoring objects (setfable)."
-    (let ((*current-backend* backend)
-          (*read-eval* nil))
+    (let* ((backend (backend-designator->backend designator))
+           (*current-backend* backend)
+           (*read-eval* nil))
       (handler-bind ((error (lambda (c)
                               (signal (make-condition 'restore-error
                                                       :caused-by c)))))
@@ -143,7 +140,7 @@
     "Restore the object found in stream PLACE using backend BACKEND.
      Checks the magic-number and invokes backend-restore-object"
     (check-magic-number backend place)
-    (backend-restore-object place backend))
+    (backend-restore-object backend place))
   (:method ((backend backend) (place string))
     "Restore the object found in file designator PLACE using backend BACKEND."
     (restore-from-file place backend))
@@ -152,10 +149,7 @@
     (restore-from-file place backend)))
 
 (defun restore-from-file (place backend)
-  (let* ((backend-type (stream-type backend))
-         (element-type (ecase backend-type
-                         (character 'character)
-                         (integer '(unsigned-byte 8)))))
+  (let* ((element-type (stream-type backend)))
     (with-open-file (s place :element-type element-type :direction :input)
       (backend-restore backend s))))
      
@@ -164,18 +158,10 @@
   (:documentation "Backends supporting multiple return values
 should define a custom storer and restorer for this class"));
 
-(defmacro multiple-value-store (values-form place 
-                                &optional (backend '*default-backend*))
-  "Store all values returned from VALUES-FORM into PLACE"
-  `(let ((vals (multiple-value-list ,values-form)))
-    (store (make-instance 'values-object :vals vals)
-     ,place ,backend)
-    (apply #'values vals)))
-
 (defun (setf restore) (new-val place)
   (store new-val place))
 
-(defgeneric check-magic-number (stream backend)
+(defgeneric check-magic-number (backend stream)
   (:method ((backend backend) (stream t))
     (let ((magic-number (magic-number backend)))
       (declare (type (or null ub32) magic-number))
@@ -195,47 +181,33 @@
 (defun lookup-reader (val readers)
   (gethash val readers))
 
-(defgeneric get-next-reader (place backend)
+(defgeneric get-next-reader (backend place)
   (:documentation 
    "Method which must be specialized for BACKEND to return 
    the next function to restore an object from PLACE.
    If no reader is found return a second value which will be included 
    in the error.")
-  (:method ((place t) (backend backend))
+  (:method ((backend backend) (place t))
+   (declare (ignore place))
     "The default, throw an error."
     (restore-error "get-next-reader must be specialized for backend ~(~A~)."
                    (name backend))))
 
-(defun find-function-for-type (place backend)
-  (declare (type backend backend))
-;;   (:documentation 
-;;    "Return a function registered with defrestore-? which knows
-;;    how to retrieve an object from PLACE, uses get-next-reader.")
-;;   (:method ((place t) (backend backend))
-    (multiple-value-bind (val info) (get-next-reader place backend)
-      (let ((reader (lookup-reader val (restorer-funs backend))))
-        (cond ((and val reader) (values reader val))
-              ((not val) 
-               (restore-error "~A is not registered with backend ~(~A~)."
-                              (or info "Unknown Type") (name backend)))
-              ((not reader)
-               (restore-error "No restorer defined for ~A in backend ~(~A~)."
-                              val (name backend)))))))
-
 ;; Wrapper for backend-restore-object so we don't have to pass
 ;; a backend object around all the time
 (declaim (inline restore-object))
 (defun restore-object (place &optional (backend *current-backend*))
   "Restore the object in PLACE using BACKEND"
-  (backend-restore-object place backend))
-
+  (backend-restore-object backend place))
 
-(defgeneric backend-restore-object (place backend)
+(defgeneric backend-restore-object (backend place)
   (:documentation
    "Find the next function to call with BACKEND and invoke it with PLACE.")
-  (:method ((place t) (backend backend))
+  (:method ((backend backend) (place t))
     "The default"
-    (funcall (the function (find-function-for-type place backend)) place)))
+    (internal-restore-object backend (get-next-reader backend place) place)))
+
+(defgeneric internal-restore-object (backend type place))
 
 
 ;; EOF


Index: cl-store/tests.lisp
diff -u cl-store/tests.lisp:1.13 cl-store/tests.lisp:1.14
--- cl-store/tests.lisp:1.13	Tue Feb  1 09:27:26 2005
+++ cl-store/tests.lisp	Fri Feb 11 13:00:31 2005
@@ -172,15 +172,20 @@
 
 
 ;; hash tables
+; for some reason (make-hash-table) is not equalp 
+; to (make-hash-table) with ecl.
+
+#-ecl
 (deftestit hash.1 (make-hash-table))
 
-(deftestit hash.2
-  (let ((val #.(let ((in (make-hash-table :test #'equal 
+#-ecl
+(defvar *hash* (let ((in (make-hash-table :test #'equal 
                                           :rehash-threshold 0.4 :size 20
                                           :rehash-size 40)))
                  (dotimes (x 1000) (setf (gethash (format nil "~R" x) in) x))
-                 in)))
-    val))
+                 in))
+#-ecl
+(deftestit hash.2 *hash*)
 
 
 ;; packages
@@ -211,7 +216,7 @@
 (deftest standard-object.2
   (let ((val (store (make-instance 'bar
                                    :x (list 1 "foo" 1.0)
-                                   :y (make-hash-table :test #'equal))
+                                   :y #(1 2 3 4))
                     *test-file*)))
     (let ((ret (restore *test-file*)))
       (and (equalp (get-x val) (get-x ret))
@@ -467,22 +472,10 @@
   t)
 
 
-(deftest values.1 
-  (progn (multiple-value-store (values 1 2 3) *test-file*)
-         (multiple-value-list (restore *test-file*)))
-  (1 2 3))
-
-(deftest values.2 
-  (let ((string "foo"))
-    (multiple-value-store (values string string) *test-file*)
-    (let ((val (multiple-value-list (restore *test-file*))))
-      (eq (car val) (cadr val))))
-  t)
-
 
 (deftestit function.1 #'restores)
 (deftestit function.2 #'car)
-#-(or clisp lispworks allegro openmcl)
+#-(or clisp lispworks allegro openmcl ecl)
 (deftestit function.3 #'(setf car))
 
 (deftestit gfunction.1 #'cl-store:restore)


Index: cl-store/utils.lisp
diff -u cl-store/utils.lisp:1.10 cl-store/utils.lisp:1.11
--- cl-store/utils.lisp:1.10	Thu Feb  3 12:55:13 2005
+++ cl-store/utils.lisp	Fri Feb 11 13:00:31 2005
@@ -94,5 +94,13 @@
 (defun kwd (name)
   (values (intern (string-upcase name) :keyword)))
 
+(defun mkstr (&rest args)
+  (with-output-to-string (s)
+    (dolist (x args)
+      (princ x s))))
+
+(defun symbolicate (&rest syms)
+  "Concatenate all symbol names into one big symbol"
+  (values (intern (apply #'mkstr syms))))
 
 ;; EOF




More information about the Cl-store-cvs mailing list