[gambit-list] write and GUI
Marc Feeley
feeley at iro.umontreal.ca
Sat May 9 09:57:49 EDT 2009
On 8-May-09, at 3:32 PM, Claude Marinier wrote:
> Greetings,
>
> I have been building a library catalogue application in Gambit-C. It
> can
> import CSV, build indexes, and perform searches. It is now time to
> think
> about storing this in a file. Does the write function produce output
> which
> can be used to recreate the data structures I saved? If yes, how is
> this
> done?
You can do that using binary serialization (preferred because it is
more compact) or textual serialization (useful for debugging because
it is somewhat humanly readable). Check the sample code below.
Marc
;; Method #1 (uses binary serialization)
(define (save1 obj filename)
(call-with-output-file
filename
(lambda (p)
(let ((v (object->u8vector obj)))
(write-subu8vector v 0 (u8vector-length v) p)))))
(define (restore1 filename)
(let ((size (file-size filename)))
(call-with-input-file
filename
(lambda (p)
(let ((v (make-u8vector size)))
(if (not (= size (read-subu8vector v 0 size p)))
(error "file size inconsistency")
(u8vector->object v)))))))
;; Method #2 (uses textual serialization)
(define (save2 obj filename)
(call-with-output-file
filename
(lambda (p)
(output-port-readtable-set!
p
(readtable-sharing-allowed?-set
(output-port-readtable p)
'serialize))
(write obj p))))
(define (restore2 filename)
(call-with-input-file
filename
(lambda (p)
(input-port-readtable-set!
p
(readtable-sharing-allowed?-set
(input-port-readtable p)
'serialize))
(read p))))
;; Test by creating a database and saving/restoring it both ways.
;; The database contains cycles. So this test shows that
;; saving/restoring preserves sharing and cycles.
(define-type person
id: 99d2e11d-a556-46c6-a468-c4fa546114fc ;; required for
serialization
name
children
unprintable:
parent)
(define a (make-person "alice" '() #f))
(define b (make-person "bob" '() #f))
(define c (make-person "chuck" (list a b) #f))
(person-parent-set! a c)
(person-parent-set! b c)
(define db
(list (cons "alice" a)
(cons "bob" b)
(cons "chuck" c)))
(define (get db key)
(cdr (assoc key db)))
;; save/restore using both methods and check that all is well
;; method #1
(save1 db "db1.bin")
(define db1 (restore1 "db1.bin"))
(pp (person-children (get db1 "chuck")))
(pp (eq? (person-parent (get db1 "alice"))
(get db1 "chuck")))
;; method #2
(save2 db "db2.txt")
(define db2 (restore2 "db2.txt"))
(pp (person-children (get db2 "chuck")))
(pp (eq? (person-parent (get db2 "alice"))
(get db2 "chuck")))
;; output:
;;
;; (#<person #2 name: "alice" children: ()>
;; #<person #3 name: "bob" children: ()>)
;; #t
;; (#<person #4 name: "alice" children: ()>
;; #<person #5 name: "bob" children: ()>)
;; #t
More information about the Gambit-list
mailing list