* Object dumper for Scheme48 This library defines a generalized object dumper for Scheme48. It not only supports dumping of most Scheme data, but also user-provided object decomposers & recomposers. Taylor Campbell wrote this code and this associated documentation; he places it in the public domain. ** Structure layout OBJECT-DUMP Exports all of the public object dumper-related procedures; this is just a combination of DUMPING, RETRIEVING-DUMPS, USUAL-DUMP-ENCODER, and USUAL-DUMP-DECODER. DUMPING Exports everything related to the core dump creation interface. RETRIEVING-DUMPS Exports everything related to the core dump retrieval interface. USUAL-DUMP-ENCODER USUAL-DUMP-DECODER Exports a dump encoder or decoder, respectively, that operates on most Scheme data, including numbers, pairs, symbols, vectors, cells, weak pointers, strings, and byte vectors. Notable exceptions include records, which should be encoded in an application-specific manner; closures, continuations, & templates, which are very tricky subjects; and locations, which are very application-specific. Ports & channels are also not dumpable, but that's for obvious reasons. I'm wary about dumping shared bindings, as well. *** Structure DUMPING Before actually writing out object dumps, they need to be collected in structures called dumpsters that handle shared objects in the object graphs of the objects that are dumped. User-visibly, they have only one field, the encoder; this is the user-provided function for encoding user data. (MAKE-DUMPSTER ) -> dumpster Dumpster constructor. (GET-ENCODER ) -> [immediate? key encoder] IMMEDIATE? specifies whether or not OBJECT need be a vertex in the object graph -- #F indicates that it need not be --. KEY is the key used to encode OBJECT. ENCODER is a procedure that takes two arguments, a dumpster and the object, and dumps the object's contents. If KEY is #F, an error is signalled to the effect that OBJECT could not be dumped. (DUMPSTER? ) -> boolean Dumpster type predicate. (DUMP []) -> unspecified The main dumping routine. DUMP invokes ENCODER, or, if that argument is not passed, DUMPSTER's encoder, on OBJECT and saves the serialized output in DUMPSTER. If OBJECT is not encoded as an immediate, DUMP also stores OBJECT in a table of objects to refer back to in later dumps. (DUMP-USING-WRITER ) -> unspcified An alternative dumping routine; this does not update the object graph at all, but instead it provides a way to write data directly to the port that an object dump is written to. When this writer is met during an object dump write -- by WRITE-DUMP or WRITE-DUMP-TO-FILE --, it is applied to the port that the dump is being written to. This is most useful when writing custom dumpers. (DUMP-BYTE ) -> unspecified (DUMP-CHAR ) -> unspecified (DUMP-BLOCK ) -> unspecified Various dumpers for basic data. These should be used _only_ with the intent of explicitly reading them back in a decoder routine with READ-CHAR et cetera; it would not work to later call RETRIEVE to get them back. (DUMP-INTEGER ) -> unspecified DUMP-INTEGER dumps an exact, non-negative integer, which will be encoded as a sequence of base-128 digits in bytes whose eighth bit is not set, until the last byte, where it is set. The seven-bit digits are dumped low-order-first. INTEGER may therefore be arbitrarily large. Integers dumped with DUMP-INTEGER should be retrieved using RETRIEVE-INTEGER. (WRITE-DUMP ) -> unspecified WRITE-DUMP writes out the object graph that was serialized into DUMPSTER, to PORT. (WRITE-DUMP-TO-FILE ) -> unspecified Convenience for writing an object dump to a file. (CALL-WITH-FILE-DUMPSTER ) -> values (CALL-WITH-PORT-DUMPSTER ) -> values Conveniences for setting up dumpsters and writing their dumps. CALL-WITH-FILE-DUMPSTER passes a dumpster with the given encoder to RECEIVER; when RECEIVER returns, CALL-WITH-FILE-DUMPSTER opens an output port on FILENAME, writes to that port the dump that RECEIVER collected in the dumpster, closes the port, and returns the values that RECEIVER returned. CALL-WITH-PORT-DUMPSTER does similarly, but, rather than opening a port on a file & subsequently closing it, it just writes to PORT. *** Structure RETRIEVING-DUMPS When reading back in an object dump, a record of the object graph that was serialized must be stored; the retriever data type encapsulates this storage. (OPEN-RETRIEVER ) -> retriever (MAKE-RETRIEVER ) -> retriever Retriever constructors. OPEN-RETRIEVER opens a new input port from FILENAME and passes that to MAKE-RETRIEVER. MAKE-RETRIEVER in turn consumes input from PORT: it reads the dump's header. The retriever uses GET-DECODER to decode individual objects from dumps. (GET-DECODER ) -> decoder or #F Returns a procedure that decodes/retrieves an object from a dump given a retriever, port, & registrar procedure. KEY is what the corresponding GET-ENCODER, of the dumpster that made the dump, returned. If GET-DECODER returns #F, an error is signalled to the effect that it cannot decode the given key. The decoder may retrieve objects from the retriever or read them directly from the input port. If the object to be retrieved is non-immediate, it should be passed to the unary registrar procedure before any of its general fields, fields which may point to other vertices in the object graph, are initialized: this is so that circular components of the object graph may be retrieved without entering infinite loops. The decoder procedure should return the object it decoded. (RETRIEVER? ) -> boolean Retriever predicate. (RETRIEVE []) -> value The object graph vertex reader. This reads a single vertex in the object graph, updating every new vertex read and using old vertices that were previously read. Objects are decoded by passing the appropriate decoder procedure, as obtained by calling DECODER, or, if that argument is absent, RETRIEVER's decoder, on the symbolic key that the object was encoded with. (RETRIEVE/CHECK []) -> value Like RETRIEVE, but this adds the convenience of checking the value that was retrieved. If the value does not satisfy PREDICATE, an error is signalled to the effect that the object dump was corrupt. (RETRIEVE-INTEGER ) -> exact, non-negative integer Retrieves an integer in the encoding as dumped by DUMP-INTEGER from RETRIEVER. (CALL-WITH-FILE-RETRIEVER ) -> values Convenience for retrieving. This handles the opening & closing of FILENAME; it opens FILENAME, creates a retriever with the port that corresponds with FILENAME and DECODER, and applies RECEIVER to it; when RECEIVER returns, it closes the port and returns the value that RECEIVER returned. (CLOSE-RETRIEVER ) -> unspecified Closes the port underlying RETRIEVER and destroys any references it had to the object graph it retrieved. *** Structure USUAL-DUMP-ENCODER (USUAL-DUMP-ENCODER ) -> [immediate? key encoder] This is a dump encoder, suitable for passing to MAKE-DUMPSTER, for most Scheme data. See above for details. *** Structure USUAL-DUMP-DECODER (USUAL-DUMP-DECODER ) -> decoder or #F This is a dump decoder, suitable for passing to MAKE-RETRIEVER or OPEN-RETRIEVER, for most Scheme data. It is intended to be used as the inverse of USUAL-DUMP-DECODER. ** Bugs, problems, et cetera If you find bugs, please send them to Taylor Campbell, who can be reached by email at campbell@bloodandcoffee.net or on IRC in #scheme and #scsh on irc.freenode.net under the nick Riastradh.