Subject: Re: with-output-to-unsigned-byte-8-array ?
From: rpw3@rpw3.org (Rob Warnock)
Date: Fri, 20 Jul 2007 05:30:41 -0500
Newsgroups: comp.lang.lisp
Message-ID: <Wcqdnd-p5e5MEz3bnZ2dnUVZ_gidnZ2d@speakeasy.net>
Liu Fung Sin  <fungsin.lui@gmail.com> wrote:
+---------------
| With the help of cl-store's serialization support, I'm trying to store
| a list of integers into a column (type bytea, which is an blob of data
| of type unsigned byte 8) to a postgresql database.
| 
| Is there a portable way to hack up a handy macro like with-output-to-
| string for (unsigned-byte 8) data stream?
| 
| (with-output-to-unsigned-byte-8-array (out)
|   ;; write ascii "abc"
|   (write-byte 97 out)
|   (write-byte 98 out)
|   (write-byte 99 out))
| 
| => return a '(VECTOR (UNSIGNED-BYTE 8)) with content #(97 98 99)
+---------------

Unfortunately, the CLHS provides no standardized way [AFAIK] to extend
streams beyond the normal variants, but almost every implementation
provides [or has available for it] some version of "Gray streams" (q.v.),
which provides a stream type whose behavior is provided by user code
[somewhat similar to PTYs or TUNs, if you're familiar with those, which
provide a specific driver type on one side for which emulation of the
"hardware" is provided by user-mode software on the other side], see:

    http://www.nhplace.com/kent/CL/Issues/stream-definition-by-user.html
    http://franz.com/support/documentation/6.0/doc/gray-streams.htm
    http://www.cliki.net/trivial-gray-streams
    http://www.cliki.net/simple-stream
    http://www.franz.com/support/documentation/6.2/doc/streams.htm
    http://common-lisp.net/project/cmucl/doc/cmu-user/extensions.html#toc45

So assuming the implementation you use has some version of Gray streams
or simple-streams available, you could define a subsclass of one of
those that, when opened, creates an adjustable (UNSIGNED-BYTE 8)
vector with an initial fill pointer of zero, and on each "write" type
call does a VECTOR-PUSH-EXTEND on the vector with the value written,
plus provide a hook to get at the vector to return it, then define your
WITH-OUTPUT-TO-UNSIGNED-BYTE-8-ARRAY macro to wrap all of that around
the &BODY of a call to the macro.

[If I were adept at Gray streams or simple-streams myself, I'd cheerfully
provide you with a working example at this point. But sadly I am not,
and someone else will have to that bit...]


-Rob

-----
Rob Warnock			<rpw3@rpw3.org>
627 26th Avenue			<URL:http://rpw3.org/>
San Mateo, CA 94403		(650)572-2607