Coverage report: /home/ellis/comp/core/std/serde.lisp
Kind | Covered | All | % |
expression | 0 | 102 | 0.0 |
branch | 0 | 10 | 0.0 |
Key
Not instrumented
Conditionalized out
Executed
Not executed
Both branches taken
One branch taken
Neither branch taken
1
;;; std/serde.lisp --- Basic Lisp Serializer API
3
;; Read/Write Lisp Objects.
7
;; This package contains macros for defining a pair of functions for a
8
;; category of lisp types - a READ-* function and a WRITE-* function. These
9
;; functions operate on a storage context which we Serialize (write) and Deserialize
10
;; (read) values from.
12
;; Within the STD system we implement the API for octet vectors as well as
13
;; (ALIEN (* UNSIGNED-CHAR)). These are used by higher-level packages which
14
;; need to portably serialize lisp objects as octet vectors.
17
(in-package :std/serde)
20
(define-condition serde-condition () ()
21
(:documentation "Default SERDE condition class."))
22
(deferror serde-error (serde-condition) ()
23
(:documentation "An error signaled during serialization OR deserialization.")))
25
(deferror serializer-error (serde-error)
27
(:documentation "An error which occurs during object serialization."))
29
(deferror deserializer-error (serde-error)
31
(:documentation "An error which occurs during object deserialization."))
34
(defgeneric serializable-p (self)
35
(:method ((self t)) nil)
36
(:documentation "Return non-nil of object SELF is serializable."))
38
(defgeneric serialize (obj format &key &allow-other-keys)
39
(:documentation "Serialize OBJ to FORMAT, which is a SERIALIZABLE-TYPE-DESIGNATOR."))
41
(defgeneric deserializable-p (self)
42
(:method ((self t)) nil)
43
(:documentation "Return non-nil if object SELF is deserializable."))
45
(defgeneric deserialize (from format &key &allow-other-keys)
46
(:documentation "Deserialize FROM into an object of type FORMAT, which is a
47
DESERIALIZABLE-TYPE-DESIGNATOR."))
49
(defgeneric ser (self)
50
(:documentation "Access the serializer of SELF."))
51
(defgeneric (setf ser) (new self))
53
(:documentation "Access the deserializer of SELF."))
54
(defgeneric (setf de) (new self))
56
(defgeneric serde (from to)
57
(:documentation "Point-to-point serialization.
59
FROM and TO should both specialize on object instances.
61
Calling this function requires you to initialize the arguments instead
62
of relying on a type-designator format and generating an object in the
65
(defparameter *primitive-object-table*
66
(let ((tbl (make-hash-table)))
67
(dolist (obj *primitive-objects* tbl)
68
(setf (gethash (primitive-object-name obj) tbl) (cons (symbol-value (primitive-object-lowtag obj)) (symbol-value (primitive-object-widetag obj))))))
69
"Primitive objects are defined by SBCL and will not change. Convenient as a
70
non-unique ID prefix.")
72
(defparameter *simple-objects*
73
(apply 'vector '(fixnum
74
character single-float
80
standard-object struct
83
"A vector containing the simple set of lisp objects.")
85
(defvar *core-object-table* (make-hash-table)
86
"A hash-table mapping PRIMITIVE-TYPE names to integers.")
88
(definline prim-type (obj)
89
"Return the name of the primitive type of OBJ."
90
(sb-vm::primitive-type-name (primitive-type-of obj)))
92
(declaim (inline %lisp-object-id))
93
(defun %lisp-object-id (obj)
94
"Return the STD/SERDE 'id' of OBJ - which is its position in *SIMPLE-LISP-OBJECTS*."
95
(position obj *simple-objects*))
97
(defmacro define-io (name &body body)
98
"Define a set of readers and writers of category NAME.
100
BODY contains elements of the form:
102
(OBJECT &KEY READ WRITE)"
105
(defmacro ,(symbolicate 'read- name) (ty from)
106
`(,(intern (string (symbolicate 'read- ',name '- ty)) ,*package*) ,from))
107
(defmacro ,(symbolicate 'write- name) (ty obj to)
108
`(,(intern (string (symbolicate 'write- ',name '- ty)) ,*package*) ,to ,obj))
109
,@(loop for form in body
111
(let* ((type (car form))
112
(type-name (if (consp type)
113
(format nil "~@[~{~A-~^~A~}~]" type)
115
(rfn (symbolicate 'read- name '- type-name))
116
(wfn (symbolicate 'write- name '- type-name)))
117
`(,@(when-let ((rf (cdr (assoc :read (cdr form)))))
119
`((defun ,rfn ,(car rf) ,@(if (atom #1#) (list #1#) #1#)))))
120
,@(when-let ((wf (cdr (assoc :write (cdr form)))))
122
`((defun ,wfn ,(car wf) ,@(if (atom #2#) (list #2#) #2#)))))))))))