| Allegro CL version 10.1 Unrevised from 10.0 to 10.1. 10.0 version | ||||||||||
Arguments: (var &optional buffer &key external-format) forms
Similar to with-output-to-string but with an octet buffer
(a vector that is a simple-array with element
type (unsigned-byte 8) or
(signed-byte 8)) instead of a Lisp string. The
external-format argument should be the name of an
external-format,
or :default. :default will
cause the external format to be looked up in the locale. with-output-to-buffer is implemented using a
buffer-output-simple-stream.
The return value depends on the value of the buffer argument. Return values are described below.
The buffer argument can either be an octet
buffer (described above), or nil, or
unsupplied (unsupplied is not the same
as nil), or :growable
(equivalent to unsupplied). If an octet buffer is supplied, an error
will be signaled if the buffer
overflows. The :growable value is necessary because
some value must be supplied when a value is given for
the external-format keyword argument.
If buffer is unsupplied
or :growable, a suitable buffer is created and
used. That buffer extends automatically as needed and so cannot
overflow. The contents are available in the body of this macro
using get-output-stream-buffer.
If buffer
is nil, the stream acts like a counting
bit-bucket: no output is generated, and so no overflow can occur, but
the file-position of the stream can be queried at the end of the
write. This allows the following to be done:
cl-user(1): (with-output-to-buffer (stm nil)
(write-string "hello" stm)
(file-position stm))
5
cl-user(2):
This macro returns the contents of the created buffer
if buffer is unsupplied
or :growable. If buffer is an
octet array or nil, this macro returns, as
multiple values, all values returned by the last form of the body.
;; buffer not supplied
cl-user(3): (with-output-to-buffer (b)
(values (write-string "hello" b) 1 2 3))
#(104 101 108 108 111)
;; buffer eq :growable
cl-user(5): (with-output-to-buffer (b :growable)
(values (write-string "hello" b) 1 2 3))
#(104 101 108 108 111)
;; buffer = nil
cl-user(4): (with-output-to-buffer (b nil)
(values (write-string "hello" b) (file-position b) 'more 'output))
"hello"
5
more
output
;; non-nil buffer supplied
cl-user(12): (with-output-to-buffer
(b (make-array 20 :element-type '(unsigned-byte 8)))
(values (write-string "hello" b) 1 2 3))
"hello"
1
2
3
;; non-nil buffer supplied but it is too small,
;; so an error is signaled:
cg-user(13): (with-output-to-buffer
(b (make-array 10 :element-type '(unsigned-byte 8)))
(values (write-string "hello, how are you today?" b) 1 2 3))
Error: In sc-write-char-direct: Output exceeds workspace for #<buffer-output-simple-stream pos 10 @ #x202796082>
[condition type: simple-error]
cg-user(14):
The macro with-underlying-simple-vector may be
useful in conjunction with this macro as it allows
any (unsigned-byte 8) or
(signed-byte 8) array (not just simple one or just
vectors) to be effectively used as the buffer.
An aligned pointer is a fixnum which is interpreted as a machine
integer, as described in Aligned Pointers and the :aligned
type in ftype.htm. The lower 2 (for 32-bit
Lisps) or 3 (for 64-bit Lisps) bits of a positive fixnum are zeros
which identify the value as a positive fixnum. With the correct
specification (as an :aligned value) such fixnums
can be passed unconverted to foreign code where they are interpreted
as 32 or 64 bit integers whose lower 2 or 3 bits happen to be 0.
Thus if such a fixnum corresponding, as an aligned pointer to values in foreign space, is given as the value of the buffer argument, Lisp will take values from that location from start up to (but not including) end. Note that end must be given a non-negative fixnum value. It is an error if no value is specified for end (since Lisp has then no way of knowing where the data of interest ends).
;; Here is a simple example. We get some C space with
;; aclmalloc-aligned, fill it with
;; values and access the values. Note that a value is specified for
;; the END keyword argument.
(defun x ()
(let ((buf (aclmalloc-aligned 4096)))
(unwind-protect
(progn
;; Populate buf with sample data
(dotimes (n 10)
(setf (sys:memref buf n 0 :unsigned-byte) n))
(with-input-from-buffer (stream buf
:start 0 :end 10
:external-format :utf-8)
(dotimes (n 10)
(format t "~a => ~a~%" n (read-byte stream)))
;; Expect eof
(read-byte stream)))
;; Cleanup forms
(aclfree-aligned buf))))
0
cl-user(3): :cf foo
;;; Compiling file foo.cl
;;; Writing fasl file foo.fasl
;;; Fasl write complete
cl-user(4): :ld foo
; Fast loading foo.fasl
cl-user(5): (x)
0 => 0
1 => 1
2 => 2
3 => 3
4 => 4
5 => 5
6 => 6
7 => 7
8 => 8
9 => 9
Error: eof encountered on stream
#<buffer-input-simple-stream pos 10 @ #x10003aec882>
[condition type: end-of-file]
See streams.htm for information on the simple-streams implementation in Allegro CL.
Copyright (c) 1998-2019, Franz Inc. Oakland, CA., USA. All rights reserved.
This page was not revised from the 10.0 page.
Created 2019.8.20.
| Allegro CL version 10.1 Unrevised from 10.0 to 10.1. 10.0 version | ||||||||||