Subject: Re: How to write binary data to standard out?
From: rpw3@rpw3.org (Rob Warnock)
Date: Tue, 04 Jul 2006 03:05:18 -0500
Newsgroups: comp.lang.lisp
Message-ID: <SLWdnR-FQpujvDfZnZ2dnUVZ_oSdnZ2d@speakeasy.net>
Pascal Bourguignon  <pjb@informatimago.com> wrote:
+---------------
| "goose" <ruse@webmail.co.za> writes:
| > Quick question: How can I write a string to that output?
| > format and print both fail. I'd like to mix raw bytes and
| > common strings on the same output (and input).
| 
| You cannot.  Strings contain characters, not bytes.
| Well, you can encode a string into a byte sequence.
| For example: ...
| (defun string-encode-ascii (string)
|   (coerce (loop :for ch :across string ...)
|           'vector))
| (string-encode-ascii "Hello World!")
| --> #(72 101 108 108 111 32 87 111 114 108 100 33)
+---------------

Plain ol' MAP should also work:

    > (map 'vector 'char-code "Hello World!")

    #(72 101 108 108 111 32 87 111 114 108 100 33)
    > 

And then one should able to use WRITE-SEQUENCE on the resulting vector.
WITH-OUTPUT-TO-STRING is handy for capturing the text to MAP. Putting it
all together:

    > (with-open-file (s "/dev/fd/1" :direction :output
				     :if-exists :append
				     :element-type '(unsigned-byte 8))
	(write-byte 128 s)
	(write-sequence (map 'vector 'char-code
			     (with-output-to-string (str)
			       (format str "Hello, world!")
			       (print 'a-symbol str)
			       (terpri str)))  
			s)
	(write-byte 129 s))
    Hello, world!
    A-SYMBOL 

    129
    > 


-Rob

p.s. The #x80 & #x81 bytes didn't cut & paste above, but they were there:

$ cmucl -quiet -load foo.lisp -eval '(quit)' | hexdump -C
00000000  80 48 65 6c 6c 6f 2c 20  77 6f 72 6c 64 21 0a 41  |.Hello, world!.A|
00000010  2d 53 59 4d 42 4f 4c 20  0a 81                    |-SYMBOL ..|
0000001a
$ 

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