[LISPWORKS][Common Lisp HyperSpec (TM)] [Previous][Up][Next]


Issue READ-AND-WRITE-BYTES Writeup

Issue:        READ-AND-WRITE-BYTES

Reference: X3J13/92-102, dpANS 12.24

X3J13/92-2601, Jeremy Wertheimer comment #1

Category: ADDITION

Edit History: Version 1, 1/5/92, Kim Barrett

Status: Proposal NEW-FUNCTIONS passed (5+3)-3 on letter ballot 93-302.

Problem Description:

Common Lisp should have a facility for reading and writing blocks of

binary bytes. The lack of such a facility makes it impossible to write

portable efficient programs to access binary files. This lack might make

common lisp unsuitable for various applications such as database management

and image processing. This lack is not simply a matter of convenience that

could be remedied by user programming. If the standard does not provide at

least one method for efficiently reading and writing blocks of binary bytes,

users cannot later construct one using available common lisp facilities.

In addition, some users have complained about the lack of a non-consing

variant of READ-STRING, to which an existing string could be passed to receive

the data.

Proposal (READ-AND-WRITE-BYTES:NEW-FUNCTIONS):

Add the following dictionary entries to Chapter 21, Streams.

%%% ========== READ-SEQUENCE

\begincom{read-sequence}\ftype{Function}

\label Syntax::

\DefunWithValues {read-sequence} {sequence stream {\key} start end} {position}

\param{sequence}---a \term{sequence}.

\param{stream}---an \term{input} \term{stream}.

\param{start}, \param{end}---\term{bounding index designators} of

\param{sequence}. \Defaults{\param{start} and \param{end}}{\f{0} and \nil}

\param{position}---an \term{integer} greater than or equal to zero, and

less than or equal to the \term{length} of the \param{sequence}.

\label Description::

Destructively modifies \param{sequence} by replacing the \term{elements}

of \param{sequence} \term{bounded} by \param{start} and \param{end} with

\term{elements} read from \param{stream}.

\param{Sequence} is destructively modified by copying successive

\term{elements} into it from \param{stream}. If the \term{end of file} for

\param{stream} is reached before copying all \term{elements} of the

subsequence, then the extra \term{elements} near the end of \param{sequence}

are not updated.

\param{Position} is the index of the first \term{element} of \param{sequence}

that was not updated, which might be less than \param{end} because the

\term{end of file} was reached.

\label Examples::

\code

(defvar *data* (make-array 15 :initial-element nil))

(values (read-sequence *data* (make-string-input-stream "test string")) *data*)

\EV 11, #(#\t #\e #\s #\t #\Space #\s #\t #\r #\i #\n #\g NIL NIL NIL NIL)

\endcode

\label Side Effects::

Modifies \param{stream} and \param{sequence}.

\label Affected By:\None

\label Exceptional Situations::

\Lazychecktype{sequence}{a \term{proper sequence}}

\Shouldchecktype{start}{a non-negative \term{integer}}

\Shouldchecktype{end}{a non-negative \term{integer} or \nil}

Might signal an error \oftype{type-error} if an \term{element} read from

the \param{stream} is not a member of the \term{element type} of the

\param{sequence}.

\label See Also::

{\secref\ConstantModification}, \funref{write-sequence}, \funref{read-line}

\label Notes::

\funref{read-sequence} is identical in effect to iterating over the indicated

subsequence and reading one \term{element} at a time from \param{stream} and

storing it into \param{sequence}, but may be more efficient than the

equivalent loop. An efficient implementation is more likely to exist

for the case where the \param{sequence} is a \term{vector} with the same

\term{element type} as the \param{stream}.

%%% ========== WRITE-SEQUENCE

\begincom{write-sequence}\ftype{Function}

\label Syntax::

\DefunWithValues {write-sequence} {sequence stream {\key} start end} {sequence}

\param{sequence}---a \term{sequence}.

\param{stream}---an \term{output} \term{stream}.

\param{start}, \param{end}---\term{bounding index designators} of

\param{sequence}. \Defaults{\param{start} and \param{end}}{\f{0} and \nil}

\label Description::

\funref{write-sequence} writes the \term{elements} of the subsequence

of \param{sequence} \term{bounded} by \param{start} and \param{end} to

\param{stream}.

\label Examples::

\code

(write-sequence "bookworms" *standard-output* :end 4)

\OUT book

\EV "bookworms"

\endcode

\label Side Effects::

Modifies \param{stream}.

\label Affected By:\None

\label Exceptional Situations::

\Lazychecktype{sequence}{a \term{proper sequence}}

\Shouldchecktype{start}{a non-negative \term{integer}}

\Shouldchecktype{end}{a non-negative \term{integer} or \nil}

Might signal an error \oftype{type-error} if an \term{element} of the

\term{bounded} \term{sequence} is not a member of the

\term{stream element type} of the \param{stream}.

\label See Also::

{\secref\ConstantModification}, \funref{read-sequence}, \funref{write-string},

\funref{write-line}

\label Notes::

\funref{write-sequence} is identical in effect to iterating over the indicated

subsequence and writing one \term{element} at a time to \param{stream}, but

may be more efficient than the equivalent loop. An efficient implementation

is more likely to exist for the case where the \param{sequence} is a

\term{vector} with the same \term{element type} as the \param{stream}.

Editorial Impact:

Just drop in a couple more dictionary entries. Might want to add a few more

cross references.

Rationale:

Addresses the problem description.

Current Practice:

Symbolics Genera provides :string-in and :string-out operations on streams

that could easily be used to implement these functions.

IIM Common Lisp provides functions with similar capabilities but under

slightly different names.

Cost to Implementors:

Depends on the details of the implementation of the stream operators, but

probably not very difficult in most cases. Getting maximum efficiency might

require some significant work, but some of that work has probably already

been done to support existing operators or extensions.

Cost to Users:

None. This is an upwardly compatible addition.

Performance Impact:

Some existing code that uses iteration could be rewritten to use the new

operators, with a potentially substantial improvement in performance.

Benefits:

Improved performance, and clearer code.

Aesthetics:

The use of these operators is probably clearer than the corresponding

iteration code, and therefor more aesthetic.


[Starting Points][Contents][Index][Symbols][Glossary][Issues]
Copyright 1996-2005, LispWorks Ltd. All rights reserved.