source: trunk/source/doc/src/streams.xml @ 8981

Last change on this file since 8981 was 8981, checked in by mikel, 11 years ago

additions to ObjC and ffi docs; many mechanical edits; some standardization of XML elements and formatting

File size: 33.7 KB
Line 
1<?xml version="1.0" encoding="utf-8"?>
2<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
3          <!ENTITY rest "<varname>&amp;rest</varname>">
4          <!ENTITY key "<varname>&amp;key</varname>">
5          <!ENTITY optional "<varname>&amp;optional</varname>">
6          <!ENTITY body "<varname>&amp;body</varname>">
7          <!ENTITY aux "<varname>&amp;aux</varname>">
8          <!ENTITY allow-other-keys "<varname>&amp;allow-other-keys</varname>">
9          <!ENTITY CCL "Clozure CL">
10          ]>
11
12<chapter id="Streams">
13  <title>Streams</title>
14
15  <sect1 id="CCL-Stream-Extensions">
16    <title>Stream Extensions</title>
17    <sect2 id="Stream-Timeouts-And-Deadlines">
18      <title>Stream Timeouts and Deadlines</title>
19      <indexterm>
20        <primary>stream-input-timeout</primary>
21      </indexterm>
22      <indexterm>
23        <primary>stream-output-timeout</primary>
24      </indexterm>
25      <indexterm>
26        <primary>stream-deadline</primary>
27      </indexterm>
28      <indexterm>
29        <primary>input-timeout</primary>
30      </indexterm>
31      <indexterm>
32        <primary>output-timeout</primary>
33      </indexterm>
34      <indexterm>
35        <primary>communication-deadline-expired</primary>
36      </indexterm>
37      <para>A stream that is associated with a file descriptor has
38        attributes and accessors:
39        <function>STREAM-INPUT-TIMEOUT</function>,
40        <function>STREAM-OUTPUT-TIMEOUT</function>, and
41        <function>STREAM-DEADLINE</function>.  All three accessors have
42        corresponding <function>SETF</function> methods.
43        <function>STREAM-INPUT-TIMEOUT</function> and
44        <function>STREAM-OUTPUT-TIMEOUT</function> are specified in
45        seconds and can be any positive real number less than one million.
46        When a timeout is set and the corresponding I/O operation takes
47        longer than the specified interval, an error is signalled.  The
48        error is <literal>INPUT-TIMEOUT</literal> for input and
49        <literal>OUTPUT-TIMEOUT</literal> for output.
50        <literal>STREAM-DEADLINE</literal> specifies an absolute time in
51        internal-time-units.  If an I/O operation on the stream does not
52        complete before the deadline then a
53        <literal>COMMUNICATION-DEADLINE-EXPIRED</literal> error is
54        signalled.  A deadline takes precedence over any
55        input/output timeouts that may be set.</para>
56    </sect2>
57
58    <sect2 id="Open-File-Streams">
59      <title>Open File Streams</title>
60      <para>Historically, &CCL; and MCL maintained a list of open
61        file streams in the value of
62        <literal>CCL:*OPEN-FILE-STREAMS*</literal>.  This functionality
63        has been replaced with the thread-safe function:
64        <literal>CCL:OPEN-FILE-STREAMS</literal> and its two helper
65        functions: <literal>CCL:NOTE-OPEN-FILE-STREAM</literal> and
66        <literal>CCL:REMOVE-OPEN-FILE-STREAM</literal>.  Maintaining
67        this list helps to ensure that streams get closed in an orderly
68        manner when the lisp exits.</para>
69
70      <refentry id="f_open-file-streams">
71            <indexterm zone="f_open-file-streams">
72              <primary>open-file-streams</primary>
73            </indexterm>
74
75            <refnamediv>
76              <refname>OPEN-FILE-STREAMS</refname>
77              <refpurpose>Returns the list of file streams that are currently open.</refpurpose>
78              <refclass>Function</refclass>
79            </refnamediv>
80
81            <refsynopsisdiv>
82              <synopsis>
83                <function>open-file-streams</function>
84                => stream-list
85              </synopsis>
86            </refsynopsisdiv>
87
88            <refsect1>
89              <title>Values</title>
90             
91              <variablelist>
92                <varlistentry>
93                  <term>stream-list</term>
94                  <listitem>
95                        <para>A list of open file streams.  This is a copy of
96                          an internal list so it may be destructively
97                          modified without ill effect.</para>
98                  </listitem>
99                </varlistentry>
100              </variablelist>
101            </refsect1>
102
103            <refsect1>
104              <title>Description</title>
105              <para>Returns a list of open file streams.</para>
106            </refsect1>
107
108            <refsect1>
109              <title>See Also</title>   
110              <simplelist type="inline">
111                <member><xref linkend="f_note-open-file-stream"/></member>
112                <member><xref linkend="f_remove-open-file-stream"/></member>
113              </simplelist>
114            </refsect1>
115      </refentry>
116
117      <refentry id="f_note-open-file-stream">
118            <indexterm zone="f_note-open-file-stream">
119              <primary>note-open-file-stream</primary>
120            </indexterm>
121
122            <refnamediv>
123              <refname>NOTE-OPEN-FILE-STREAM</refname>
124              <refpurpose>Adds a file stream to the internal list of open
125                file streams that is returned by
126                <function>note-open-file-stream</function>.</refpurpose>
127              <refclass>Function</refclass>
128            </refnamediv>
129
130            <refsynopsisdiv>
131              <synopsis>
132                <function>note-open-file-stream</function>
133                file-stream
134              </synopsis>
135            </refsynopsisdiv>
136
137            <refsect1>
138              <title>Arguments</title>
139             
140              <variablelist>
141                <varlistentry>
142                  <term>file-stream</term>
143                  <listitem>
144                        <para>A file stream.</para>
145                  </listitem>
146                </varlistentry>
147              </variablelist>
148            </refsect1>
149
150            <refsect1>
151              <title>Description</title>
152              <para>Adds a file stream to the internal list of open
153                file streams that is returned by
154                <function>open-file-streams</function>.  This function is
155                thread-safe.  It will usually only be called from custom
156                stream code when a file-stream is created.</para>
157            </refsect1>
158
159            <refsect1>
160              <title>See Also</title>   
161              <simplelist type="inline">
162                <member><xref linkend="f_open-file-streams"/></member>
163                <member><xref linkend="f_remove-open-file-stream"/></member>
164              </simplelist>
165            </refsect1>
166
167      </refentry>
168
169      <refentry id="f_remove-open-file-stream">
170            <indexterm zone="f_remove-open-file-stream">
171              <primary>remove-open-file-stream</primary>
172            </indexterm>
173
174            <refnamediv>
175              <refname>REMOVE-OPEN-FILE-STREAM</refname>
176              <refpurpose>Removes file stream from the internal list of open
177                file streams that is returned by
178                <function>open-file-streams</function>.</refpurpose>
179              <refclass>Function</refclass>
180            </refnamediv>
181
182            <refsynopsisdiv>
183              <synopsis>
184                <function>remove-open-file-stream</function>
185                file-stream
186              </synopsis>
187            </refsynopsisdiv>
188
189            <refsect1>
190              <title>Arguments</title>
191             
192              <variablelist>
193                <varlistentry>
194                  <term>file-stream</term>
195                  <listitem>
196                        <para>A file stream.</para>
197                  </listitem>
198                </varlistentry>
199              </variablelist>
200            </refsect1>
201
202            <refsect1>
203              <title>Description</title>
204              <para>Remove file stream from the internal list of open file
205                streams that is returned by
206                <function>open-file-streams</function>.  This function is
207                thread-safe.  It will usually only be called from custom
208                stream code when a file-stream is closed.</para>
209            </refsect1>
210
211            <refsect1>
212              <title>See Also</title>   
213              <simplelist type="inline">
214                <member><xref linkend="f_open-file-streams"/></member>
215                <member><xref linkend="f_note-open-file-stream"/></member>
216              </simplelist>
217            </refsect1>
218
219      </refentry>
220
221    </sect2>
222  </sect1>
223
224  <sect1 id="Creating-Your-Own-Stream-Classes-with-Gray-Streams">
225    <title>Creating Your Own Stream Classes with Gray Streams</title>
226
227    <sect2 id="Streams-Overview">
228      <title>Overview</title>
229      <para>This sect1 is still being written and revised, because
230        it is woefully incomplete.  The dictionary section currently
231        only lists a couple functions.  Caveat lector.</para>
232      <para>Gray streams are an extension to Common Lisp.  They were
233        proposed for standardization by David Gray (the astute reader
234        now understands their name) quite some years ago, but not
235        accepted, because they had not been tried sufficiently to find
236        conceptual problems with them.</para>
237      <para>They have since been implemented by quite a few modern
238        Lisp implementations.  However, they do indeed have some
239        inadequacies, and each implementation has addressed these in
240        different ways.  The situation today is that it's difficult to
241        even find out how to get started using Gray streams.  This is
242        why standards are important.</para>
243      <para>Here's a list of some classes which you might wish for
244        your new stream class to inherit from:</para>
245     
246      <simplelist>
247            <member>fundamental-stream</member>
248            <member>fundamental-input-stream</member>
249            <member>fundamental-output-stream</member>
250            <member>fundamental-character-stream</member>
251            <member>fundamental-binary-stream</member>
252            <member>fundamental-character-input-stream</member>
253            <member>fundamental-character-output-stream</member>
254            <member>fundamental-binary-input-stream</member>
255            <member>fundamental-binary-output-stream</member>
256            <member>ccl::buffered-stream-mixin</member>
257            <member>ccl::buffered-input-stream-mixin</member>
258            <member>ccl::buffered-output-stream-mixin</member>
259            <member>ccl::buffered-io-stream-mixin</member>
260            <member>ccl::buffered-character-input-stream-mixin</member>
261            <member>ccl::buffered-character-output-stream-mixin</member>
262            <member>ccl::buffered-character-io-stream-mixin</member>
263            <member>ccl::buffered-binary-input-stream-mixin</member>
264            <member>ccl::buffered-binary-output-stream-mixin</member>
265            <member>ccl::buffered-binary-io-stream-mixin</member>
266            <member>file-stream</member>
267            <member>file-input-stream</member>
268            <member>file-output-stream</member>
269            <member>file-io-stream</member>
270            <member>file-character-input-stream</member>
271            <member>file-character-output-stream</member>
272            <member>file-character-io-stream</member>
273            <member>file-binary-input-stream</member>
274            <member>file-binary-output-stream</member>
275            <member>file-binary-io-stream</member>
276            <member>ccl::fd-stream</member>
277            <member>ccl::fd-input-stream</member>
278            <member>ccl::fd-output-stream</member>
279            <member>ccl::fd-io-stream</member>
280            <member>ccl::fd-character-input-stream</member>
281            <member>ccl::fd-character-output-stream</member>
282            <member>ccl::fd-character-io-stream</member>
283            <member>ccl::fd-binary-input-stream</member>
284            <member>ccl::fd-binary-output-stream</member>
285            <member>ccl::fd-binary-io-stream</member>
286      </simplelist>
287
288      <para>All of these are defined in ccl/level-1/l1-streams.lisp,
289        except for the ccl:file-* ones, which are in
290        ccl/level-1/l1-sysio.lisp.</para>
291      <para>According to the original Gray streams proposal, you
292        should inherit from the most specific of the fundamental-*
293        classes which applies.  Using &CCL;, though, if you want
294        buffering for better performance, which, unless you know of some
295        reason you wouldn't, you do, you should instead inherit from the
296        appropriate ccl::buffered-* class The buffering you get this way
297        is exactly the same as the buffering which is used on ordinary,
298        non-Gray streams, and force-output will work properly on
299        it.</para>
300      <para>Notice that -mixin suffix in the names of all the
301        ccl::buffered-* classes?  The suffix means that this class is
302        not "complete" by itself; you still need to inherit from a
303        fundamental-* stream, even if you also inherit from a *-mixin
304        stream.  You might consider making your own class like this.
305        ....  Except that they do inherit from the fundamental-*
306        streams, that's weird.</para>
307      <para>If you want to be able to create an instance of your class
308        with the :class argument to (open) and (with-open-file), you
309        should make it inherit from one of the file-* classes.  If you
310        do this, it's not necessary to inherit from any of the other
311        classes (though it won't hurt anything), since the file-*
312        classes already do.</para>
313      <para>When you inherit from the file-* classes, you can use
314        (call-next-method) in any of your methods to get the standard
315        behavior.  This is especially useful if you want to create a
316        class which performs some simple filtering operation, such as
317        changing everything to uppercase or to a different character
318        encoding.  If you do this, you will definitely need to
319        specialize ccl::select-stream-class.  Your method on
320        ccl::stream-select-class should accept an instance of the class,
321        but pay no attention to its contents, and return a symbol naming
322        the class to actually be instantiated.</para>
323      <para>If you need to make your functionality generic across all
324        the different types of stream, probably the best way to
325        implement it is to make it a mixin, define classes with all the
326        variants of input, output, io, character, and binary, which
327        inherit both from your mixin and from the appropriate other
328        class, then define a method on ccl::select-stream-class which
329        chooses from among those classes.</para>
330      <para>Note that some of these classes are internal to the CLL
331        package.  If you try to inherit from those ones without the
332        ccl:: prefix, you'll get an error which may confuse you, calling
333        them "forward-referenced classes".  That just means you used the
334        wrong symbol, so add the prefix.</para>
335      <para>Here's a list of some generic functions which you might
336        wish to specialize for your new stream class, and which ought to
337        be documented at some point.</para>
338      <simplelist>
339            <member>stream-direction stream =></member>
340            <member>stream-device stream direction =></member>
341            <member>stream-length stream &optional; new =></member>
342            <member>stream-position stream &optional; new =></member>
343            <member>streamp stream => boolean</member>
344            <member>stream-write-char output-stream char =></member>
345            <member>stream-write-entire-string output-stream string =></member>
346            <member>stream-read-char input-stream =></member>
347            <member>stream-unread-char input-stream char =></member>
348            <member>stream-force-output output-stream => nil</member>
349            <member>stream-maybe-force-output output-stream => nil</member>
350            <member>stream-finish-output output-stream => nil</member>
351            <member>stream-clear-output output-stream => nil</member>
352            <member>close stream &key; abort => boolean</member>
353            <member>stream-fresh-line stream => t</member>
354            <member>stream-line-length stream => length</member>
355            <member>interactive-stream-p stream => boolean</member>
356            <member>stream-clear-input input-stream => nil</member>
357            <member>stream-listen input-stream => boolean</member>
358            <member>stream-filename stream => string</member>
359            <member>ccl::select-stream-class instance in-p out-p char-p =>
360              class</member>
361      </simplelist>
362      <para>The following functions are standard parts of Common Lisp, but
363        behave in special ways with regard to Gray streams.</para>
364      <simplelist>
365            <member>open-stream-p stream => generalized-boolean</member>
366            <member>input-stream-p stream => generalized-boolean</member>
367            <member>output-stream-p stream => generalized-boolean</member>
368            <member>stream-element-type stream =></member>
369            <member>stream-error-stream =></member>
370            <member>open</member>
371            <member>close</member>
372            <member>with-open-file</member>
373      </simplelist>
374
375      <para>Specifically, (open) and (with-open-file) accept a new
376        keyword argument, :class, which may be a symbol naming a class;
377        the class itself; or an instance of it.  The class so given must
378        be a subtype of 'stream, and an instance of it with no
379        particular contents will be passed to ccl::select-stream-class
380        to determine what class to actually instantiate.</para>
381      <para>The following are standard, and do not behave specially
382        with regard to Gray streams, but probably should.</para>
383      <simplelist>
384            <member>stream-external-format</member>
385      </simplelist>
386    </sect2>
387
388    <sect2 id="Extending-READ-SEQUENCE-and-WRITE-SEQUENCE">
389      <title>Extending READ-SEQUENCE and WRITE-SEQUENCE</title>
390
391      <sect3 id="extending-read-write-overview">
392            <title>Overview</title>
393            <para>The "Gray Streams" API is based on an informal proposal that was
394              made before ANSI CL adopted the READ-SEQUENCE and WRITE-SEQUENCE
395              functions; as such, there is no "standard" way for the author of a Gray
396              stream class to improve the performance of these functions by exploiting
397              knowledge of the stream's internals (e.g., the buffering mechanism it
398              uses.)</para>
399            <para>In the absence of any such knowledge, READ-SEQUENCE and
400              WRITE-SEQUENCE are effectively just convenient shorthand for a
401              loop which calls READ-CHAR/READ-BYTE/WRITE-CHAR/WRITE-BYTE as
402              appropriate. The mechanism described below allows subclasses
403              of FUNDAMENTAL-STREAM to define more specialized (and
404              presumably more efficient) behavior.</para>
405      </sect3>
406
407      <sect3 id="Notes">
408            <title>Notes</title>
409            <para>READ-SEQUENCE and WRITE-SEQUENCE do a certain amount of
410              sanity-checking and normalization of their arguments before
411              dispatching to one of the methods above. If an individual
412              method can't do anything particularly clever, CALL-NEXT-METHOD
413              can be used to handle the general case.</para>
414      </sect3>
415
416      <sect3 id="Example">
417            <title>Example</title>
418            <programlisting>
419(defclass my-string-input-stream (fundamental-character-input-stream)
420  ((string :initarg :string :accessor my-string-input-stream-string)
421   (index :initform 0 :accessor my-string-input-stream-index)
422   (length)))
423
424(defmethod stream-read-vector ((stream my-string-input-stream) vector start end)
425  (if (not (typep vector 'simple-base-string))
426      (call-next-method)
427      (with-slots (string index length)
428              (do* ((outpos start (1+ outpos)))
429               ((or (= outpos end)
430                    (= index length))
431                outpos))
432        (setf (schar vector outpos)
433              (schar string index))
434        (incf index)))))
435            </programlisting>
436      </sect3>
437    </sect2>
438
439    <sect2 id="Multibyte-I-O">
440      <title>Multibyte I/O</title>
441      <para>All heap-allocated objects in &CCL; that cannot contain
442        pointers to lisp objects are represented as
443        <emphasis>ivectors</emphasis>. &CCL; provides low-level
444        functions, and , to efficiently transfer data between buffered
445        streams and ivectors. There's some overlap in functionality
446        between the functions described here and the ANSI CL
447        READ-SEQUENCE and WRITE-SEQUENCE functions.</para>
448      <para>As used here, the term "octet" means roughly the same
449        thing as the term "8-bit byte". The functions described below
450        transfer a specified sequence of octets between a buffered
451        stream and an ivector, and don't really concern themselves with
452        higher-level issues (like whether that octet sequence is within
453        bounds or how it relates to the logical contents of the
454        ivector.) For these reasons, these functions are generally less
455        safe and more flexible than their ANSI counterparts.</para>
456    </sect2>
457
458    <sect2 id="Gray-Streams-Dictionary">
459      <title>Gray Streams Dictionary</title>
460      <refentry id="f_stream-read-list">
461            <indexterm zone="f_stream-read-list">
462              <primary>stream-read-list</primary>
463            </indexterm>
464
465            <refnamediv>
466              <refname>CCL:STREAM-READ-LIST</refname>
467              <refpurpose></refpurpose>
468              <refclass>Generic Function</refclass>
469            </refnamediv>
470
471            <refsynopsisdiv>
472              <synopsis><function>stream-read-list</function>
473                stream list count</synopsis>
474            </refsynopsisdiv>
475
476            <refsect1>
477              <title>Arguments and Values</title>
478
479              <variablelist>
480                <varlistentry>
481                  <term>stream</term>
482
483                  <listitem>
484                        <para>a stream, presumably a fundamental-input-stream.</para>
485                  </listitem>
486                </varlistentry>
487
488                <varlistentry>
489                  <term>list</term>
490
491                  <listitem>
492                        <para>a list. When a STREAM-READ-LIST method is called by
493                          READ-SEQUENCE, this argument is guaranteed to be a proper
494                          list.</para>
495                  </listitem>
496                </varlistentry>
497
498                <varlistentry>
499                  <term>count</term>
500
501                  <listitem>
502                        <para>a non-negative integer. When a STREAM-READ-LIST method
503                          is called by READ-SEQUENCE, this argument is guaranteed not
504                          to be greater than the length of the list.</para>
505                  </listitem>
506                </varlistentry>
507              </variablelist>
508            </refsect1>
509
510            <refsect1>
511              <title>Description</title>
512
513              <para>Should try to read up to count elements from stream into the
514                list list, returning the number of elements actually read (which
515                may be less than count in case of a premature end-of-file.)</para>
516            </refsect1>
517      </refentry>
518
519      <refentry id="f_stream-write-list">
520            <indexterm zone="f_stream-write-list">
521              <primary>stream-write-list</primary>
522            </indexterm>
523
524            <refnamediv>
525              <refname>CCL:STREAM-WRITE-LIST</refname>
526              <refpurpose></refpurpose>
527              <refclass>Generic Function</refclass>
528            </refnamediv>
529
530            <refsynopsisdiv>
531              <synopsis><function>stream-write-list</function>
532                stream list count</synopsis>
533            </refsynopsisdiv>
534
535            <refsect1>
536              <title>Arguments and Values</title>
537
538              <variablelist>
539                <varlistentry>
540                  <term>stream</term>
541
542                  <listitem>
543                        <para>a stream, presumably a fundamental-output-stream.</para>
544                  </listitem>
545                </varlistentry>
546
547                <varlistentry>
548                  <term>list</term>
549
550                  <listitem>
551                        <para>a list. When a STREAM-WRITE-LIST method is called by
552                          WRITE-SEQUENCE, this argument is guaranteed to be a proper
553                          list.</para>
554                  </listitem>
555                </varlistentry>
556
557                <varlistentry>
558                  <term>count</term>
559
560                  <listitem>
561                        <para>a non-negative integer. When a STREAM-WRITE-LIST
562                          method is called by WRITE-SEQUENCE, this argument is
563                          guaranteed not to be greater than the length of the list.</para>
564                  </listitem>
565                </varlistentry>
566              </variablelist>
567            </refsect1>
568
569            <refsect1>
570              <title>Description</title>
571
572              <para>should try to write the first count elements of list to
573                stream. The return value of this method is ignored.</para>
574            </refsect1>
575      </refentry>
576
577      <refentry id="f_stream-read-vector">
578            <indexterm zone="f_stream-read-vector">
579              <primary>stream-read-vector</primary>
580            </indexterm>
581
582            <refnamediv>
583              <refname>CCL:STREAM-READ-VECTOR</refname>
584              <refpurpose></refpurpose>
585              <refclass>Generic Function</refclass>
586            </refnamediv>
587
588            <refsynopsisdiv>
589              <synopsis><function>stream-read-vector</function>
590                stream vector start end</synopsis>
591            </refsynopsisdiv>
592
593            <refsect1>
594              <title>Arguments and Values</title>
595
596              <variablelist>
597                <varlistentry>
598                  <term>stream</term>
599
600                  <listitem>
601                        <para>a stream, presumably a fundamental-input-stream</para>
602                  </listitem>
603                </varlistentry>
604
605                <varlistentry>
606                  <term>vector</term>
607
608                  <listitem>
609                        <para>a vector. When a STREAM-READ-VECTOR method is called
610                          by READ-SEQUENCE, this argument is guaranteed to be a simple
611                          one-dimensional array.</para>
612                  </listitem>
613                </varlistentry>
614
615                <varlistentry>
616                  <term>start</term>
617
618                  <listitem>
619                        <para>a non-negative integer. When a STREAM-READ-VECTOR
620                          method is called by READ-SEQUENCE, this argument is
621                          guaranteed to be no greater than end and not greater than
622                          the length of vector.</para>
623                  </listitem>
624                </varlistentry>
625
626                <varlistentry>
627                  <term>end</term>
628
629                  <listitem>
630                        <para>a non-negative integer. When a STREAM-READ-VECTOR
631                          method is called by READ-SEQUENCE, this argument is
632                          guaranteed to be no less than end and not greater than the
633                          length of vector.</para>
634                  </listitem>
635                </varlistentry>
636              </variablelist>
637            </refsect1>
638
639            <refsect1>
640              <title>Description</title>
641
642              <para>should try to read successive elements from stream into
643                vector, starting at element start (inclusive) and continuing
644                through element end (exclusive.) Should return the index of the
645                vector element beyond the last one stored into, which may be less
646                than end in case of premature end-of-file.</para>
647            </refsect1>
648      </refentry>
649
650      <refentry id="f_stream-write-vector">
651            <indexterm zone="f_stream-write-vector">
652              <primary>stream-write-vector</primary>
653            </indexterm>
654
655            <refnamediv>
656              <refname>CCL:STREAM-WRITE-VECTOR</refname>
657              <refpurpose></refpurpose>
658              <refclass>Generic Function</refclass>
659            </refnamediv>
660
661            <refsynopsisdiv>
662              <synopsis><function>stream-write-vector</function>
663                stream vector start end</synopsis>
664            </refsynopsisdiv>
665
666            <refsect1>
667              <title>Arguments and Values</title>
668
669              <variablelist>
670                <varlistentry>
671                  <term>stream</term>
672
673                  <listitem>
674                        <para>a stream, presumably a fundamental-output-stream</para>
675                  </listitem>
676                </varlistentry>
677
678                <varlistentry>
679                  <term>vector</term>
680
681                  <listitem>
682                        <para>a vector. When a STREAM-WRITE-VECTOR method is called
683                          by WRITE-SEQUENCE, this argument is guaranteed to be a
684                          simple one-dimensional array.</para>
685                  </listitem>
686                </varlistentry>
687
688                <varlistentry>
689                  <term>start</term>
690
691                  <listitem>
692                        <para>a non-negative integer. When a STREAM-WRITE-VECTOR
693                          method is called by WRITE-SEQUENCE, this argument is
694                          guaranteed to be no greater than end and not greater than
695                          the length of vector.</para>
696                  </listitem>
697                </varlistentry>
698
699                <varlistentry>
700                  <term>end</term>
701
702                  <listitem>
703                        <para>a non-negative integer. When a STREAM-WRITE-VECTOR
704                          method is called by WRITE-SEQUENCE, this argument is
705                          guaranteed to be no less than end and not greater than the
706                          length of vector.</para>
707                  </listitem>
708                </varlistentry>
709              </variablelist>
710            </refsect1>
711
712            <refsect1>
713              <title>Description</title>
714
715              <para>should try to write successive elements of vector to stream,
716                starting at element start (inclusive) and continuing through
717                element end (exclusive.)</para>
718            </refsect1>
719      </refentry>
720
721      <refentry id="f_stream-device">
722            <indexterm zone="f_stream-device">
723              <primary>stream-device</primary>
724            </indexterm>
725
726            <refnamediv>
727              <refname>CCL::STREAM-DEVICE</refname>
728              <refpurpose>Returns the OS file descriptor associated with a
729                given lisp stream.</refpurpose>
730              <refclass>Generic Function</refclass>
731            </refnamediv>
732
733            <refsynopsisdiv>
734              <synopsis><function>ccl::stream-device</function>
735                s direction</synopsis>
736            </refsynopsisdiv>
737
738            <refsect1>
739              <title>Method Signatures</title>
740
741              <synopsis><function>ccl::stream-device</function>
742                (s stream) direction => fd</synopsis>
743            </refsect1>
744
745            <refsect1>
746              <title>Arguments and Values</title>
747             
748              <variablelist>
749                <varlistentry>
750                  <term>s</term>
751                  <listitem>
752                        <para>a stream.</para>
753                  </listitem>
754                </varlistentry>
755                <varlistentry>
756                  <term>direction</term>
757                  <listitem>
758                        <para>either :INPUT or :OUTPUT.</para>
759                  </listitem>
760                </varlistentry>
761                <varlistentry>
762                  <term>fd</term>
763                  <listitem>
764                        <para>a file descriptor, which is a non-negative integer
765                          used by the OS to refer to an open file, socket, or similar
766                          I/O connection.  NIL if there is no file descriptor associated
767                          with <varname>s</varname> in the direction given by
768                          <varname>direction</varname>.</para>
769                  </listitem>
770                </varlistentry>
771              </variablelist>
772            </refsect1>
773
774            <refsect1>
775              <title>Description</title>
776
777              <para>Returns the file descriptor associated with
778                <varname>s</varname> in the direction given by
779                <varname>direction</varname>.  It is necessary to specify
780                <varname>direction</varname> because the input and output
781                file descriptors may be different; the most common case is when
782                one of them has been redirected by the Unix shell.</para>
783            </refsect1>
784      </refentry>
785
786      <refentry id="f_stream-read-ivector">
787            <indexterm zone="f_stream-read-ivector">
788              <primary>stream-read-ivector</primary>
789            </indexterm>
790
791            <refnamediv>
792              <refname>STREAM-READ-IVECTOR</refname>
793              <refpurpose></refpurpose>
794              <refclass>Generic Function</refclass>
795            </refnamediv>
796
797            <refsynopsisdiv>
798              <synopsis><function>stream-read-ivector</function>
799                stream ivector start-octet max-octets</synopsis>
800            </refsynopsisdiv>
801
802            <refsect1>
803              <title>Description</title>
804
805              <para>Reads up to max-octets octets from stream into ivector,
806                storing them at start-octet. Returns the number of octets actually
807                read.</para>
808            </refsect1>
809
810            <refsect1>
811              <title>Arguments</title>
812
813              <variablelist>
814                <varlistentry>
815                  <term>stream</term>
816
817                  <listitem>
818                        <para>An input stream. The method defined on
819                          BUFFERED-INPUT-STREAMs requires that the size in octets of
820                          an instance of the stream's element type is 1.</para>
821                  </listitem>
822                </varlistentry>
823
824                <varlistentry>
825                  <term>ivector</term>
826
827                  <listitem>
828                        <para>Any ivector.</para>
829                  </listitem>
830                </varlistentry>
831
832                <varlistentry>
833                  <term>start-octet</term>
834
835                  <listitem>
836                        <para>A non-negative integer.</para>
837                  </listitem>
838                </varlistentry>
839
840                <varlistentry>
841                  <term>max-octets</term>
842
843                  <listitem>
844                        <para>A non-negative integer. The return value may be less
845                          than the value of this parameter if EOF was encountered.</para>
846                  </listitem>
847                </varlistentry>
848              </variablelist>
849            </refsect1>
850      </refentry>
851
852      <refentry id="f_stream-write-ivector">
853            <indexterm zone="f_stream-write-ivector">
854              <primary>stream-write-ivector</primary>
855            </indexterm>
856
857            <refnamediv>
858              <refname>STREAM-WRITE-IVECTOR</refname>
859              <refpurpose></refpurpose>
860              <refclass>Generic Function</refclass>
861            </refnamediv>
862
863            <refsynopsisdiv>
864              <synopsis><function>stream-write-ivector stream</function>
865                ivector start-octet max-octets</synopsis>
866            </refsynopsisdiv>
867
868            <refsect1>
869              <title>Description</title>
870
871              <para>Writes max-octets octets to stream from ivector, starting at
872                start-octet. Returns max-octets.</para>
873            </refsect1>
874
875            <refsect1>
876              <title>Arguments</title>
877
878              <variablelist>
879                <varlistentry>
880                  <term>stream</term>
881
882                  <listitem>
883                        <para>An input stream. The method defined on
884                          BUFFERED-OUTPUT-STREAMs requires that the size in octets of
885                          an instance of the stream's element type is 1.</para>
886                  </listitem>
887                </varlistentry>
888
889                <varlistentry>
890                  <term>ivector</term>
891
892                  <listitem>
893                        <para>Any ivector</para>
894                  </listitem>
895                </varlistentry>
896
897                <varlistentry>
898                  <term>start-octet</term>
899
900                  <listitem>
901                        <para>A non-negative integer.</para>
902                  </listitem>
903                </varlistentry>
904
905                <varlistentry>
906                  <term>max-octet</term>
907
908                  <listitem>
909                        <para>A non-negative integer.</para>
910                  </listitem>
911                </varlistentry>
912              </variablelist>
913            </refsect1>
914
915            <refsect1>
916              <title>Examples</title>
917
918              <programlisting format="linespecific">
919;;; Write the contents of a (SIMPLE-ARRAY(UNSIGNED-BYTE 16) 3)
920;;; to a character file stream. Read back the characters.
921(let* ((a (make-array 3
922                      :element-type '(unsigned-byte 16)
923                      :initial-contents '(26725 27756 28449))))
924  (with-open-file (s "junk"
925                     :element-type 'character
926                     :direction :io
927                     :if-does-not-exist :create
928                     :if-exists :supersede)
929    ;; Write six octets (three elements).
930    (stream-write-ivector s a 0 6)
931    ;; Rewind, then read a line
932    (file-position s 0)
933    (read-line s)))
934
935;;; Write a vector of DOUBLE-FLOATs. Note that (to maintain
936;;; alignment) there are 4 octets of padding before the 0th
937;;; element of a (VECTOR DOUBLE-FLOAT).
938;;; (Note that (= (- arch::misc-dfloat-offset
939;;;                  arch::misc-data-offset) 4))
940(defun write-double-float-vector
941    (stream vector &#38;key (start 0) (end (length vector)))
942     (check-type vector (vector double-float))
943     (let* ((start-octet (+ (* start 8)
944                            (- arch::misc-dfloat-offset
945                               arch::misc-data-offset)))
946                (num-octets (* 8 (- end start))))
947       (stream-write-ivector stream vector start-octet num-octets)))
948          </programlisting>
949            </refsect1>
950      </refentry>
951    </sect2>
952  </sect1>
953</chapter>
Note: See TracBrowser for help on using the repository browser.