[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