1 /* Generic stream implementation.
2 Copyright (C) 1995 Free Software Foundation, Inc.
3 Copyright (C) 1995 Sun Microsystems, Inc.
4 Copyright (C) 1996 Ben Wing.
6 This file is part of XEmacs.
8 XEmacs is free software; you can redistribute it and/or modify it
9 under the terms of the GNU General Public License as published by the
10 Free Software Foundation; either version 2, or (at your option) any
13 XEmacs is distributed in the hope that it will be useful, but WITHOUT
14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
18 You should have received a copy of the GNU General Public License
19 along with XEmacs; see the file COPYING. If not, write to
20 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA. */
23 /* Synched up with: Not in FSF. */
25 /* Written by Ben Wing. */
38 /* This function provides a generic buffering stream implementation.
39 Conceptually, you send data to the stream or read data from the
40 stream, not caring what's on the other end of the stream. The
41 other end could be another stream, a file descriptor, a stdio
42 stream, a fixed block of memory, a reallocating block of memory,
43 etc. The main purpose of the stream is to provide a standard
44 interface and to do buffering. Macros are defined to read
45 or write characters, so the calling functions do not have to
46 worry about blocking data together in order to achieve efficiency.
49 /* Note that this object is called "stream" in Lisp but "lstream"
50 in C. The reason for this is that "stream" is too generic a name
51 for C; too much likelihood of conflict/confusion with C++, etc. */
53 /* Functions are as follows:
55 Lstream *Lstream_new (Lstream_implementation *imp, CONST char *mode)
56 Allocate and return a new Lstream. This function is not
57 really meant to be called directly; rather, each stream type
58 should provide its own stream creation function, which
59 creates the stream and does any other necessary creation
60 stuff (e.g. opening a file).
62 void Lstream_set_buffering (Lstream *lstr, Lstream_buffering buffering,
64 Change the buffering of a stream. See lstream.h. By default
65 the buffering is STREAM_BLOCK_BUFFERED.
67 int Lstream_flush (Lstream *lstr)
68 Flush out any pending unwritten data in the stream. Clear
69 any buffered input data. Returns 0 on success, -1 on error.
71 int Lstream_putc (Lstream *stream, int c)
72 Write out one byte to the stream. This is a macro and so
73 it is very efficient. The C argument is only evaluated once
74 but the STREAM argument is evaluated more than once. Returns
75 0 on success, -1 on error.
77 int Lstream_getc (Lstream *stream)
78 Read one byte from the stream. This is a macro and so it
79 is very efficient. The STREAM argument is evaluated more
80 than once. Return value is -1 for EOF or error.
82 void Lstream_ungetc (Lstream *stream, int c)
83 Push one byte back onto the input queue. This will be the
84 next byte read from the stream. Any number of bytes can be
85 pushed back and will be read in the reverse order they were
86 pushed back -- most recent first. (This is necessary for
87 consistency -- if there are a number of bytes that have been
88 unread and I read and unread a byte, it needs to be the first
89 to be read again.) This is a macro and so it is very
90 efficient. The C argument is only evaluated once but the
91 STREAM argument is evaluated more than once.
93 int Lstream_fputc (Lstream *stream, int c)
94 int Lstream_fgetc (Lstream *stream)
95 void Lstream_fungetc (Lstream *stream, int c)
96 Function equivalents of the above macros.
98 ssize_t Lstream_read (Lstream *stream, void *data, size_t size)
99 Read SIZE bytes of DATA from the stream. Return the number of
100 bytes read. 0 means EOF. -1 means an error occurred and no
103 ssize_t Lstream_write (Lstream *stream, void *data, size_t size)
104 Write SIZE bytes of DATA to the stream. Return the number of
105 bytes written. -1 means an error occurred and no bytes were
108 void Lstream_unread (Lstream *stream, void *data, size_t size)
109 Push back SIZE bytes of DATA onto the input queue. The
110 next call to Lstream_read() with the same size will read the
111 same bytes back. Note that this will be the case even if
112 there is other pending unread data.
114 int Lstream_delete (Lstream *stream)
115 Frees all memory associated with the stream is freed. Calling
116 this is not strictly necessary, but it is much more efficient
117 than having the Lstream be garbage-collected.
119 int Lstream_close (Lstream *stream)
120 Close the stream. All data will be flushed out.
122 void Lstream_reopen (Lstream *stream)
123 Reopen a closed stream. This enables I/O on it again.
124 This is not meant to be called except from a wrapper routine
125 that reinitializes variables and such -- the close routine
126 may well have freed some necessary storage structures, for
129 void Lstream_rewind (Lstream *stream)
130 Rewind the stream to the beginning.
133 #define DEFAULT_BLOCK_BUFFERING_SIZE 512
134 #define MAX_READ_SIZE 512
137 mark_lstream (Lisp_Object obj)
139 Lstream *lstr = XLSTREAM (obj);
140 return lstr->imp->marker ? (lstr->imp->marker) (obj) : Qnil;
144 print_lstream (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag)
146 Lstream *lstr = XLSTREAM (obj);
149 sprintf (buf, "#<INTERNAL OBJECT (XEmacs bug?) (%s lstream) 0x%lx>",
150 lstr->imp->name, (long) lstr);
151 write_c_string (buf, printcharfun);
155 finalize_lstream (void *header, int for_disksave)
157 /* WARNING WARNING WARNING. This function (and all finalize functions)
158 may get called more than once on the same object, and may get called
159 (at dump time) on objects that are not being released. */
160 Lstream *lstr = (Lstream *) header;
162 #if 0 /* this may cause weird Broken Pipes? */
165 Lstream_pseudo_close (lstr);
169 if (lstr->flags & LSTREAM_FL_IS_OPEN)
173 if (lstr->flags & LSTREAM_FL_CLOSE_AT_DISKSAVE)
174 Lstream_close (lstr);
178 Lstream_close (lstr);
183 sizeof_lstream (CONST void *header)
185 CONST Lstream *lstr = (CONST Lstream *) header;
186 return sizeof (*lstr) + lstr->imp->size - 1;
189 DEFINE_LRECORD_SEQUENCE_IMPLEMENTATION ("stream", lstream,
190 mark_lstream, print_lstream,
191 finalize_lstream, 0, 0, 0,
192 sizeof_lstream, Lstream);
195 Lstream_set_buffering (Lstream *lstr, Lstream_buffering buffering,
198 lstr->buffering = buffering;
201 case LSTREAM_UNBUFFERED:
202 lstr->buffering_size = 0; break;
203 case LSTREAM_BLOCK_BUFFERED:
204 lstr->buffering_size = DEFAULT_BLOCK_BUFFERING_SIZE; break;
205 case LSTREAM_BLOCKN_BUFFERED:
206 lstr->buffering_size = buffering_size; break;
207 case LSTREAM_LINE_BUFFERED:
208 case LSTREAM_UNLIMITED:
209 lstr->buffering_size = INT_MAX; break;
213 static CONST Lstream_implementation *lstream_types[32];
214 static Lisp_Object Vlstream_free_list[32];
215 static int lstream_type_count;
218 Lstream_new (CONST Lstream_implementation *imp, CONST char *mode)
223 for (i = 0; i < lstream_type_count; i++)
225 if (lstream_types[i] == imp)
229 if (i == lstream_type_count)
231 assert (lstream_type_count < countof (lstream_types));
232 lstream_types[lstream_type_count] = imp;
233 Vlstream_free_list[lstream_type_count] =
234 make_lcrecord_list (sizeof (*p) + imp->size - 1,
236 lstream_type_count++;
239 p = XLSTREAM (allocate_managed_lcrecord (Vlstream_free_list[i]));
240 /* Zero it out, except the header. */
241 memset ((char *) p + sizeof (p->header), 0,
242 sizeof (*p) - sizeof (p->header) + imp->size - 1);
244 Lstream_set_buffering (p, LSTREAM_BLOCK_BUFFERED, 0);
245 p->flags = LSTREAM_FL_IS_OPEN;
247 /* convert mode (one of "r", "w", "rc", "wc") to p->flags */
248 assert (mode[0] == 'r' || mode[0] == 'w');
249 assert (mode[1] == 'c' || mode[1] == '\0');
250 p->flags |= (mode[0] == 'r' ? LSTREAM_FL_READ : LSTREAM_FL_WRITE);
252 p->flags |= LSTREAM_FL_NO_PARTIAL_CHARS;
258 Lstream_set_character_mode (Lstream *lstr)
260 lstr->flags |= LSTREAM_FL_NO_PARTIAL_CHARS;
264 Lstream_delete (Lstream *lstr)
269 XSETLSTREAM (val, lstr);
270 for (i = 0; i < lstream_type_count; i++)
272 if (lstream_types[i] == lstr->imp)
274 free_managed_lcrecord (Vlstream_free_list[i], val);
282 #define Lstream_internal_error(reason, lstr) \
283 Lstream_signal_simple_error ("Internal error: " reason, lstr)
285 static void Lstream_signal_simple_error (CONST char *reason, Lstream *lstr)
288 XSETLSTREAM (obj, lstr);
289 signal_simple_error (reason, obj);
293 Lstream_reopen (Lstream *lstr)
295 if (lstr->flags & LSTREAM_FL_IS_OPEN)
296 Lstream_internal_error ("lstream already open", lstr);
297 lstr->flags |= LSTREAM_FL_IS_OPEN;
300 /* Attempt to flush out all of the buffered data for writing. */
303 Lstream_flush_out (Lstream *lstr)
307 while (lstr->out_buffer_ind > 0)
309 size_t size = lstr->out_buffer_ind;
310 if (! (lstr->flags & LSTREAM_FL_IS_OPEN))
311 Lstream_internal_error ("lstream not open", lstr);
312 if (! (lstr->flags & LSTREAM_FL_WRITE))
313 Lstream_internal_error ("lstream not open for writing", lstr);
314 if (!lstr->imp->writer)
315 Lstream_internal_error ("lstream has no writer", lstr);
317 if (lstr->flags & LSTREAM_FL_NO_PARTIAL_CHARS)
318 /* It's quite possible for us to get passed an incomplete
319 character at the end. We need to spit back that
320 incomplete character. */
322 CONST unsigned char *data = lstr->out_buffer;
323 CONST unsigned char *dataend = data + size - 1;
324 assert (size > 0); /* safety check ... */
325 /* Optimize the most common case. */
326 if (!BYTE_ASCII_P (*dataend))
328 /* Go back to the beginning of the last (and possibly partial)
329 character, and bump forward to see if the character is
331 VALIDATE_CHARPTR_BACKWARD (dataend);
332 if (dataend + REP_BYTES_BY_FIRST_BYTE (*dataend) != data + size)
333 /* If not, chop the size down to ignore the last char
334 and stash it away for next time. */
335 size = dataend - data;
336 /* If we don't even have one character to write, then just
343 num_written = (lstr->imp->writer) (lstr, lstr->out_buffer, size);
344 if (num_written == 0)
345 /* If nothing got written, then just hold the data. This may
346 occur, for example, if this stream does non-blocking I/O;
347 the attempt to write the data might have resulted in an
348 EWOULDBLOCK error. */
350 else if (num_written >= lstr->out_buffer_ind)
351 lstr->out_buffer_ind = 0;
352 else if (num_written > 0)
354 memmove (lstr->out_buffer, lstr->out_buffer + num_written,
355 lstr->out_buffer_ind - num_written);
356 lstr->out_buffer_ind -= num_written;
359 /* If error, just hold the data, for similar reasons as above. */
363 if (lstr->imp->flusher)
364 return (lstr->imp->flusher) (lstr);
370 Lstream_flush (Lstream *lstr)
372 if (Lstream_flush_out (lstr) < 0)
375 /* clear out buffered data */
376 lstr->in_buffer_current = lstr->in_buffer_ind = 0;
377 lstr->unget_buffer_ind = 0;
382 /* We want to add NUM characters. This function ensures that the
383 buffer is large enough for this (per the buffering size specified
384 in the stream) and returns the number of characters we can
385 actually write. If FORCE is set, ignore the buffering size
386 and go ahead and make space for all the chars even if it exceeds
387 the buffering size. (This is used to deal with the possibility
388 that the stream writer might refuse to write any bytes now, e.g.
389 if it's getting EWOULDBLOCK errors. We have to keep stocking them
390 up until they can be written, so as to avoid losing data. */
393 Lstream_adding (Lstream *lstr, size_t num, int force)
395 /* Compute the size that the outbuffer needs to be after the
397 size_t size_needed = max (lstr->out_buffer_size,
398 num + lstr->out_buffer_ind);
399 /* Maybe chop it down so that we don't buffer more characters
400 than our advertised buffering size. */
402 size_needed = min (lstr->buffering_size, size_needed);
403 DO_REALLOC (lstr->out_buffer, lstr->out_buffer_size,
404 size_needed, unsigned char);
405 /* There might be more data buffered than the buffering size,
406 so make sure we don't return a negative number here. */
407 return max (0, min (num, size_needed - lstr->out_buffer_ind));
410 /* Like Lstream_write(), but does not handle line-buffering correctly. */
413 Lstream_write_1 (Lstream *lstr, CONST void *data, size_t size)
415 CONST unsigned char *p = (CONST unsigned char *) data;
417 if (! (lstr->flags & LSTREAM_FL_IS_OPEN))
418 Lstream_internal_error ("lstream not open", lstr);
419 if (! (lstr->flags & LSTREAM_FL_WRITE))
420 Lstream_internal_error ("lstream not open for writing", lstr);
422 int couldnt_write_last_time = 0;
426 /* Figure out how much we can add to the buffer */
427 size_t chunk = Lstream_adding (lstr, size, 0);
430 if (couldnt_write_last_time)
431 /* Ung, we ran out of space and tried to flush
432 the buffer, but it didn't work because the stream
433 writer is refusing to accept any data. So we
434 just have to squirrel away all the rest of the
436 chunk = Lstream_adding (lstr, size, 1);
438 couldnt_write_last_time = 1;
443 memcpy (lstr->out_buffer + lstr->out_buffer_ind, p + off, chunk);
444 lstr->out_buffer_ind += chunk;
445 lstr->byte_count += chunk;
449 /* If the buffer is full and we have more to add, flush it out. */
452 if (Lstream_flush_out (lstr) < 0)
467 /* If the stream is not line-buffered, then we can just call
468 Lstream_write_1(), which writes in chunks. Otherwise, we
469 repeatedly call Lstream_putc(), which knows how to handle
473 Lstream_write (Lstream *lstr, CONST void *data, size_t size)
476 CONST unsigned char *p = (CONST unsigned char *) data;
480 if (lstr->buffering != LSTREAM_LINE_BUFFERED)
481 return Lstream_write_1 (lstr, data, size);
482 for (i = 0; i < size; i++)
484 if (Lstream_putc (lstr, p[i]) < 0)
487 return i == 0 ? -1 : 0;
491 Lstream_was_blocked_p (Lstream *lstr)
493 return lstr->imp->was_blocked_p ? lstr->imp->was_blocked_p (lstr) : 0;
497 Lstream_raw_read (Lstream *lstr, unsigned char *buffer, size_t size)
499 if (! (lstr->flags & LSTREAM_FL_IS_OPEN))
500 Lstream_internal_error ("lstream not open", lstr);
501 if (! (lstr->flags & LSTREAM_FL_READ))
502 Lstream_internal_error ("lstream not open for reading", lstr);
503 if (!lstr->imp->reader)
504 Lstream_internal_error ("lstream has no reader", lstr);
506 return (lstr->imp->reader) (lstr, buffer, size);
509 /* Assuming the buffer is empty, fill it up again. */
512 Lstream_read_more (Lstream *lstr)
515 ssize_t size_needed = max (1, min (MAX_READ_SIZE, lstr->buffering_size));
517 /* If someone requested a larger buffer size, so be it! */
518 ssize_t size_needed = max (1, lstr->buffering_size);
522 DO_REALLOC (lstr->in_buffer, lstr->in_buffer_size,
523 size_needed, unsigned char);
524 size_gotten = Lstream_raw_read (lstr, lstr->in_buffer, size_needed);
525 lstr->in_buffer_current = max (0, size_gotten);
526 lstr->in_buffer_ind = 0;
527 return size_gotten < 0 ? -1 : size_gotten;
531 Lstream_read (Lstream *lstr, void *data, size_t size)
533 unsigned char *p = (unsigned char *) data;
536 int error_occurred = 0;
541 /* First try to get some data from the unget buffer */
542 chunk = min (size, lstr->unget_buffer_ind);
545 /* The bytes come back in reverse order. */
546 for (; off < chunk; off++)
547 p[off] = lstr->unget_buffer[--lstr->unget_buffer_ind];
548 lstr->byte_count += chunk;
554 /* Take whatever we can from the in buffer */
555 chunk = min (size, lstr->in_buffer_current - lstr->in_buffer_ind);
558 memcpy (p + off, lstr->in_buffer + lstr->in_buffer_ind, chunk);
559 lstr->in_buffer_ind += chunk;
560 lstr->byte_count += chunk;
565 /* If we need some more, try to get some more from the stream's end */
568 ssize_t retval = Lstream_read_more (lstr);
576 /* #### Beware of OFF ending up 0. */
577 if ((lstr->flags & LSTREAM_FL_NO_PARTIAL_CHARS) && off > 0)
579 /* It's quite possible for us to get passed an incomplete
580 character at the end. We need to spit back that
581 incomplete character. */
582 CONST unsigned char *dataend = p + off - 1;
583 /* Optimize the most common case. */
584 if (!BYTE_ASCII_P (*dataend))
586 /* Go back to the beginning of the last (and possibly partial)
587 character, and bump forward to see if the character is
589 VALIDATE_CHARPTR_BACKWARD (dataend);
590 if (dataend + REP_BYTES_BY_FIRST_BYTE (*dataend) != p + off)
592 size_t newoff = dataend - p;
593 /* If not, chop the size down to ignore the last char
594 and stash it away for next time. */
595 Lstream_unread (lstr, dataend, off - newoff);
601 return off == 0 && error_occurred ? -1 : (ssize_t) off;
605 Lstream_unread (Lstream *lstr, CONST void *data, size_t size)
607 CONST unsigned char *p = (CONST unsigned char *) data;
609 /* Make sure buffer is big enough */
610 DO_REALLOC (lstr->unget_buffer, lstr->unget_buffer_size,
611 lstr->unget_buffer_ind + size, unsigned char);
613 lstr->byte_count -= size;
615 /* Bytes have to go on in reverse order -- they are reversed
616 again when read back. */
618 lstr->unget_buffer[lstr->unget_buffer_ind++] = p[size];
622 Lstream_rewind (Lstream *lstr)
624 if (!lstr->imp->rewinder)
625 Lstream_internal_error ("lstream has no rewinder", lstr);
626 if (Lstream_flush (lstr) < 0)
628 lstr->byte_count = 0;
629 return (lstr->imp->rewinder) (lstr);
633 Lstream_seekable_p (Lstream *lstr)
635 if (!lstr->imp->rewinder)
637 if (!lstr->imp->seekable_p)
639 return (lstr->imp->seekable_p) (lstr);
643 Lstream_pseudo_close (Lstream *lstr)
645 if (!lstr->flags & LSTREAM_FL_IS_OPEN)
646 Lstream_internal_error ("lstream is not open", lstr);
648 /* don't check errors here -- best not to risk file descriptor loss */
649 return Lstream_flush (lstr);
653 Lstream_close (Lstream *lstr)
657 if (lstr->flags & LSTREAM_FL_IS_OPEN)
659 rc = Lstream_pseudo_close (lstr);
661 * We used to return immediately if the closer method reported
662 * failure, leaving the stream open. But this is no good, for
663 * the following reasons.
665 * 1. The finalizer method used in GC makes no provision for
666 * failure, so we must not return without freeing buffer
669 * 2. The closer method may have already freed some memory
670 * used for I/O in this stream. E.g. encoding_closer frees
671 * ENCODING_STREAM_DATA(stream)->runoff. If a writer method
672 * tries to use this buffer later, it will write into memory
673 * that may have been allocated elsewhere. Sometime later
674 * you will see a sign that says "Welcome to Crash City."
676 * 3. The closer can report failure if a flush fails in the
677 * other stream in a MULE encoding/decoding stream pair.
678 * The other stream in the pair is closed, but returning
679 * early leaves the current stream open. If we try to
680 * flush the current stream later, we will crash when the
681 * flusher notices that the other end stream is closed.
683 * So, we no longer abort the close if the closer method
684 * reports some kind of failure. We still report the failure
687 if (lstr->imp->closer)
688 if ((lstr->imp->closer) (lstr) < 0)
692 lstr->flags &= ~LSTREAM_FL_IS_OPEN;
693 lstr->byte_count = 0;
694 /* Note that Lstream_flush() reset all the buffer indices. That way,
695 the next call to Lstream_putc(), Lstream_getc(), or Lstream_ungetc()
696 on a closed stream will call into the function equivalents, which will
699 /* We set the pointers to 0 so that we don't lose when this function
700 is called more than once on the same object */
701 if (lstr->out_buffer)
703 xfree (lstr->out_buffer);
704 lstr->out_buffer = 0;
708 xfree (lstr->in_buffer);
711 if (lstr->unget_buffer)
713 xfree (lstr->unget_buffer);
714 lstr->unget_buffer = 0;
721 Lstream_fputc (Lstream *lstr, int c)
723 unsigned char ch = (unsigned char) c;
724 ssize_t retval = Lstream_write_1 (lstr, &ch, 1);
725 if (retval >= 0 && lstr->buffering == LSTREAM_LINE_BUFFERED && ch == '\n')
726 return Lstream_flush_out (lstr);
727 return retval < 0 ? -1 : 0;
731 Lstream_fgetc (Lstream *lstr)
734 if (Lstream_read (lstr, &ch, 1) <= 0)
740 Lstream_fungetc (Lstream *lstr, int c)
742 unsigned char ch = (unsigned char) c;
743 Lstream_unread (lstr, &ch, 1);
747 /************************ some stream implementations *********************/
749 /*********** a stdio stream ***********/
757 #define STDIO_STREAM_DATA(stream) LSTREAM_TYPE_DATA (stream, stdio)
759 DEFINE_LSTREAM_IMPLEMENTATION ("stdio", lstream_stdio,
760 sizeof (struct stdio_stream));
763 make_stdio_stream_1 (FILE *stream, int flags, CONST char *mode)
766 Lstream *lstr = Lstream_new (lstream_stdio, mode);
767 struct stdio_stream *str = STDIO_STREAM_DATA (lstr);
769 str->closing = flags & LSTR_CLOSING;
770 lstr->flags |= LSTREAM_FL_CLOSE_AT_DISKSAVE;
771 XSETLSTREAM (obj, lstr);
776 make_stdio_input_stream (FILE *stream, int flags)
778 return make_stdio_stream_1 (stream, flags, "r");
782 make_stdio_output_stream (FILE *stream, int flags)
784 return make_stdio_stream_1 (stream, flags, "w");
787 /* #### From reading the Unix 98 specification, it appears that if we
788 want stdio_reader() to be completely correct, we should check for
789 0 < val < size and if so, check to see if an error has occurred.
790 If an error has occurred, but val is non-zero, we should go ahead
791 and act as if the read was successful, but remember in some fashion
792 or other, that an error has occurred, and report that on the next
793 call to stdio_reader instead of calling fread() again.
795 Currently, in such a case, we end up calling fread() twice and we
798 1) this is not harmful, and
799 2) the error will still be reported on the second read.
801 This is probably reasonable, so I don't think we should change this
802 code (it could even be argued that the error might have fixed
803 itself, so we should do the fread() again. */
806 stdio_reader (Lstream *stream, unsigned char *data, size_t size)
808 struct stdio_stream *str = STDIO_STREAM_DATA (stream);
809 size_t val = fread (data, 1, size, str->file);
810 if (!val && ferror (str->file))
816 stdio_writer (Lstream *stream, CONST unsigned char *data, size_t size)
818 struct stdio_stream *str = STDIO_STREAM_DATA (stream);
819 size_t val = fwrite (data, 1, size, str->file);
820 if (!val && ferror (str->file))
826 stdio_rewinder (Lstream *stream)
828 rewind (STDIO_STREAM_DATA (stream)->file);
833 stdio_seekable_p (Lstream *stream)
836 struct stdio_stream *str = STDIO_STREAM_DATA (stream);
838 if (fstat (fileno (str->file), &lestat) < 0)
840 return S_ISREG (lestat.st_mode);
844 stdio_flusher (Lstream *stream)
846 struct stdio_stream *str = STDIO_STREAM_DATA (stream);
847 if (stream->flags & LSTREAM_FL_WRITE)
848 return fflush (str->file);
854 stdio_closer (Lstream *stream)
856 struct stdio_stream *str = STDIO_STREAM_DATA (stream);
858 return fclose (str->file);
860 if (stream->flags & LSTREAM_FL_WRITE)
861 return fflush (str->file);
866 /*********** a file descriptor ***********/
868 struct filedesc_stream
876 int chars_sans_newline;
877 unsigned int closing :1;
878 unsigned int allow_quit :1;
879 unsigned int blocked_ok :1;
880 unsigned int pty_flushing :1;
881 unsigned int blocking_error_p :1;
884 #define FILEDESC_STREAM_DATA(stream) LSTREAM_TYPE_DATA (stream, filedesc)
886 DEFINE_LSTREAM_IMPLEMENTATION ("filedesc", lstream_filedesc,
887 sizeof (struct filedesc_stream));
889 /* Make a stream that reads from or writes to a file descriptor FILEDESC.
890 OFFSET is the offset from the *current* file pointer that the reading
891 should start at. COUNT is the number of bytes to be read (it is
892 ignored when writing); -1 for unlimited. */
894 make_filedesc_stream_1 (int filedesc, int offset, int count, int flags,
898 Lstream *lstr = Lstream_new (lstream_filedesc, mode);
899 struct filedesc_stream *fstr = FILEDESC_STREAM_DATA (lstr);
901 fstr->closing = !!(flags & LSTR_CLOSING);
902 fstr->allow_quit = !!(flags & LSTR_ALLOW_QUIT);
903 fstr->blocked_ok = !!(flags & LSTR_BLOCKED_OK);
904 fstr->pty_flushing = !!(flags & LSTR_PTY_FLUSHING);
905 fstr->blocking_error_p = 0;
906 fstr->chars_sans_newline = 0;
907 fstr->starting_pos = lseek (filedesc, offset, SEEK_CUR);
908 fstr->current_pos = max (fstr->starting_pos, 0);
912 fstr->end_pos = fstr->starting_pos + count;
913 lstr->flags |= LSTREAM_FL_CLOSE_AT_DISKSAVE;
914 XSETLSTREAM (obj, lstr);
919 make_filedesc_input_stream (int filedesc, int offset, int count, int flags)
921 return make_filedesc_stream_1 (filedesc, offset, count, flags, "r");
925 make_filedesc_output_stream (int filedesc, int offset, int count, int flags)
927 return make_filedesc_stream_1 (filedesc, offset, count, flags, "w");
931 filedesc_reader (Lstream *stream, unsigned char *data, size_t size)
934 struct filedesc_stream *str = FILEDESC_STREAM_DATA (stream);
935 if (str->end_pos >= 0)
936 size = min (size, (size_t) (str->end_pos - str->current_pos));
937 nread = (str->allow_quit ? read_allowing_quit : read) (str->fd, data, size);
939 str->current_pos += nread;
944 errno_would_block_p (int val)
947 if (val == EWOULDBLOCK)
958 filedesc_writer (Lstream *stream, CONST unsigned char *data, size_t size)
960 struct filedesc_stream *str = FILEDESC_STREAM_DATA (stream);
962 int need_newline = 0;
964 /* This function would be simple if it were not for the blasted
965 PTY max-bytes stuff. Why the hell can't they just have written
966 the PTY drivers right so this problem doesn't exist?
968 Maybe all the PTY crap here should be moved into another stream
969 that does nothing but periodically insert EOF's as necessary. */
970 if (str->pty_flushing)
972 /* To make life easy, only send out one line at the most. */
973 CONST unsigned char *ptr;
975 ptr = (CONST unsigned char *) memchr (data, '\n', size);
980 if (ptr - data >= str->pty_max_bytes - str->chars_sans_newline)
982 ptr = data + str->pty_max_bytes - str->chars_sans_newline;
988 /**** start of non-PTY-crap ****/
990 retval = ((str->allow_quit ? write_allowing_quit : write)
991 (str->fd, data, size));
994 if (retval < 0 && errno_would_block_p (errno) && str->blocked_ok)
996 str->blocking_error_p = 1;
999 str->blocking_error_p = 0;
1002 /**** end non-PTY-crap ****/
1004 if (str->pty_flushing)
1006 str->chars_sans_newline += retval;
1007 /* Note that a newline was not among the bytes written out.
1008 Add to the number of non-newline bytes written out,
1009 and flush with an EOF if necessary. Be careful to
1010 keep track of write errors as we go along and look
1011 out for EWOULDBLOCK. */
1012 if (str->chars_sans_newline >= str->pty_max_bytes)
1014 ssize_t retval2 = ((str->allow_quit ? write_allowing_quit : write)
1015 (str->fd, &str->eof_char, 1));
1017 str->chars_sans_newline = 0;
1018 else if (retval2 < 0)
1020 /* Error writing the EOF char. If nothing got written,
1021 then treat this as an error -- either return an error
1022 condition or set the blocking-error flag. */
1025 if (errno_would_block_p (errno) && str->blocked_ok)
1027 str->blocking_error_p = 1;
1039 /* The need_newline flag is necessary because otherwise when the
1040 first byte is a newline, we'd get stuck never writing anything
1041 in pty-flushing mode. */
1045 ssize_t retval2 = ((str->allow_quit ? write_allowing_quit : write)
1049 str->chars_sans_newline = 0;
1052 else if (retval2 < 0)
1054 /* Error writing the newline char. If nothing got written,
1055 then treat this as an error -- either return an error
1056 condition or set the blocking-error flag. */
1059 if (errno_would_block_p (errno) && str->blocked_ok)
1061 str->blocking_error_p = 1;
1076 filedesc_rewinder (Lstream *stream)
1078 struct filedesc_stream *str = FILEDESC_STREAM_DATA (stream);
1079 if (str->starting_pos < 0 ||
1080 lseek (FILEDESC_STREAM_DATA (stream)->fd, str->starting_pos,
1085 str->current_pos = str->starting_pos;
1091 filedesc_seekable_p (Lstream *stream)
1093 struct filedesc_stream *str = FILEDESC_STREAM_DATA (stream);
1094 if (str->starting_pos < 0)
1100 if (fstat (str->fd, &lestat) < 0)
1102 return S_ISREG (lestat.st_mode);
1107 filedesc_closer (Lstream *stream)
1109 struct filedesc_stream *str = FILEDESC_STREAM_DATA (stream);
1111 return close (str->fd);
1117 filedesc_was_blocked_p (Lstream *stream)
1119 struct filedesc_stream *str = FILEDESC_STREAM_DATA (stream);
1120 return str->blocking_error_p;
1124 filedesc_stream_set_pty_flushing (Lstream *stream, int pty_max_bytes,
1127 struct filedesc_stream *str = FILEDESC_STREAM_DATA (stream);
1128 str->pty_max_bytes = pty_max_bytes;
1129 str->eof_char = eof_char;
1130 str->pty_flushing = 1;
1134 filedesc_stream_fd (Lstream *stream)
1136 struct filedesc_stream *str = FILEDESC_STREAM_DATA (stream);
1140 /*********** read from a Lisp string ***********/
1142 #define LISP_STRING_STREAM_DATA(stream) LSTREAM_TYPE_DATA (stream, lisp_string)
1144 struct lisp_string_stream
1147 Bytecount init_offset;
1148 Bytecount offset, end;
1151 DEFINE_LSTREAM_IMPLEMENTATION ("lisp-string", lstream_lisp_string,
1152 sizeof (struct lisp_string_stream));
1155 make_lisp_string_input_stream (Lisp_Object string, Bytecount offset,
1160 struct lisp_string_stream *str;
1162 CHECK_STRING (string);
1164 len = XSTRING_LENGTH (string) - offset;
1165 assert (offset >= 0);
1167 assert (offset + len <= XSTRING_LENGTH (string));
1169 lstr = Lstream_new (lstream_lisp_string, "r");
1170 str = LISP_STRING_STREAM_DATA (lstr);
1171 str->offset = offset;
1172 str->end = offset + len;
1173 str->init_offset = offset;
1175 XSETLSTREAM (obj, lstr);
1180 lisp_string_reader (Lstream *stream, unsigned char *data, size_t size)
1182 struct lisp_string_stream *str = LISP_STRING_STREAM_DATA (stream);
1183 /* Don't lose if the string shrank past us ... */
1184 Bytecount offset = min (str->offset, XSTRING_LENGTH (str->obj));
1185 Bufbyte *strstart = XSTRING_DATA (str->obj);
1186 Bufbyte *start = strstart + offset;
1188 /* ... or if someone changed the string and we ended up in the
1189 middle of a character. */
1190 /* Being in the middle of a character is `normal' unless
1191 LSTREAM_NO_PARTIAL_CHARS - mrb */
1192 if (stream->flags & LSTREAM_FL_NO_PARTIAL_CHARS)
1193 VALIDATE_CHARPTR_BACKWARD (start);
1194 offset = start - strstart;
1195 size = min (size, (size_t) (str->end - offset));
1196 memcpy (data, start, size);
1197 str->offset = offset + size;
1202 lisp_string_rewinder (Lstream *stream)
1204 struct lisp_string_stream *str = LISP_STRING_STREAM_DATA (stream);
1205 int pos = str->init_offset;
1208 /* Don't lose if the string shrank past us ... */
1209 pos = min (pos, XSTRING_LENGTH (str->obj));
1210 /* ... or if someone changed the string and we ended up in the
1211 middle of a character. */
1213 Bufbyte *strstart = XSTRING_DATA (str->obj);
1214 Bufbyte *start = strstart + pos;
1215 VALIDATE_CHARPTR_BACKWARD (start);
1216 pos = start - strstart;
1223 lisp_string_marker (Lisp_Object stream)
1225 struct lisp_string_stream *str = LISP_STRING_STREAM_DATA (XLSTREAM (stream));
1229 /*********** a fixed buffer ***********/
1231 #define FIXED_BUFFER_STREAM_DATA(stream) \
1232 LSTREAM_TYPE_DATA (stream, fixed_buffer)
1234 struct fixed_buffer_stream
1236 CONST unsigned char *inbuf;
1237 unsigned char *outbuf;
1242 DEFINE_LSTREAM_IMPLEMENTATION ("fixed-buffer", lstream_fixed_buffer,
1243 sizeof (struct fixed_buffer_stream));
1246 make_fixed_buffer_input_stream (CONST unsigned char *buf, size_t size)
1249 Lstream *lstr = Lstream_new (lstream_fixed_buffer, "r");
1250 struct fixed_buffer_stream *str = FIXED_BUFFER_STREAM_DATA (lstr);
1253 XSETLSTREAM (obj, lstr);
1258 make_fixed_buffer_output_stream (unsigned char *buf, size_t size)
1261 Lstream *lstr = Lstream_new (lstream_fixed_buffer, "w");
1262 struct fixed_buffer_stream *str = FIXED_BUFFER_STREAM_DATA (lstr);
1265 XSETLSTREAM (obj, lstr);
1270 fixed_buffer_reader (Lstream *stream, unsigned char *data, size_t size)
1272 struct fixed_buffer_stream *str = FIXED_BUFFER_STREAM_DATA (stream);
1273 size = min (size, str->size - str->offset);
1274 memcpy (data, str->inbuf + str->offset, size);
1275 str->offset += size;
1280 fixed_buffer_writer (Lstream *stream, CONST unsigned char *data, size_t size)
1282 struct fixed_buffer_stream *str = FIXED_BUFFER_STREAM_DATA (stream);
1283 if (str->offset == str->size)
1285 /* If we're at the end, just throw away the data and pretend
1286 we wrote all of it. If we return 0, then the lstream routines
1287 will try again and again to write it out. */
1290 size = min (size, str->size - str->offset);
1291 memcpy (str->outbuf + str->offset, data, size);
1292 str->offset += size;
1297 fixed_buffer_rewinder (Lstream *stream)
1299 FIXED_BUFFER_STREAM_DATA (stream)->offset = 0;
1303 CONST unsigned char *
1304 fixed_buffer_input_stream_ptr (Lstream *stream)
1306 assert (stream->imp == lstream_fixed_buffer);
1307 return FIXED_BUFFER_STREAM_DATA (stream)->inbuf;
1311 fixed_buffer_output_stream_ptr (Lstream *stream)
1313 assert (stream->imp == lstream_fixed_buffer);
1314 return FIXED_BUFFER_STREAM_DATA (stream)->outbuf;
1317 /*********** write to a resizing buffer ***********/
1319 #define RESIZING_BUFFER_STREAM_DATA(stream) \
1320 LSTREAM_TYPE_DATA (stream, resizing_buffer)
1322 struct resizing_buffer_stream
1330 DEFINE_LSTREAM_IMPLEMENTATION ("resizing-buffer", lstream_resizing_buffer,
1331 sizeof (struct resizing_buffer_stream));
1334 make_resizing_buffer_output_stream (void)
1337 XSETLSTREAM (obj, Lstream_new (lstream_resizing_buffer, "w"));
1342 resizing_buffer_writer (Lstream *stream, CONST unsigned char *data, size_t size)
1344 struct resizing_buffer_stream *str = RESIZING_BUFFER_STREAM_DATA (stream);
1345 DO_REALLOC (str->buf, str->allocked, str->stored + size, unsigned char);
1346 memcpy (str->buf + str->stored, data, size);
1347 str->stored += size;
1348 str->max_stored = max (str->max_stored, str->stored);
1353 resizing_buffer_rewinder (Lstream *stream)
1355 RESIZING_BUFFER_STREAM_DATA (stream)->stored = 0;
1360 resizing_buffer_closer (Lstream *stream)
1362 struct resizing_buffer_stream *str = RESIZING_BUFFER_STREAM_DATA (stream);
1372 resizing_buffer_stream_ptr (Lstream *stream)
1374 return RESIZING_BUFFER_STREAM_DATA (stream)->buf;
1377 /*********** write to an unsigned-char dynarr ***********/
1379 /* Note: If you have a dynarr whose type is not unsigned_char_dynarr
1380 but which is really just an unsigned_char_dynarr (e.g. its type
1381 is Bufbyte or Extbyte), just cast to unsigned_char_dynarr. */
1383 #define DYNARR_STREAM_DATA(stream) \
1384 LSTREAM_TYPE_DATA (stream, dynarr)
1386 struct dynarr_stream
1388 unsigned_char_dynarr *dyn;
1391 DEFINE_LSTREAM_IMPLEMENTATION ("dynarr", lstream_dynarr,
1392 sizeof (struct dynarr_stream));
1395 make_dynarr_output_stream (unsigned_char_dynarr *dyn)
1398 XSETLSTREAM (obj, Lstream_new (lstream_dynarr, "w"));
1399 DYNARR_STREAM_DATA (XLSTREAM (obj))->dyn = dyn;
1404 dynarr_writer (Lstream *stream, CONST unsigned char *data, size_t size)
1406 struct dynarr_stream *str = DYNARR_STREAM_DATA (stream);
1407 Dynarr_add_many (str->dyn, data, size);
1412 dynarr_rewinder (Lstream *stream)
1414 Dynarr_reset (DYNARR_STREAM_DATA (stream)->dyn);
1419 dynarr_closer (Lstream *stream)
1424 /************ read from or write to a Lisp buffer ************/
1426 /* Note: Lisp-buffer read streams never return partial characters,
1427 and Lisp-buffer write streams expect to never get partial
1430 #define LISP_BUFFER_STREAM_DATA(stream) \
1431 LSTREAM_TYPE_DATA (stream, lisp_buffer)
1433 struct lisp_buffer_stream
1436 Lisp_Object orig_start;
1437 /* we use markers to properly deal with insertion/deletion */
1438 Lisp_Object start, end;
1442 DEFINE_LSTREAM_IMPLEMENTATION ("lisp-buffer", lstream_lisp_buffer,
1443 sizeof (struct lisp_buffer_stream));
1446 make_lisp_buffer_stream_1 (struct buffer *buf, Bufpos start, Bufpos end,
1447 int flags, CONST char *mode)
1451 struct lisp_buffer_stream *str;
1453 int reading = !strcmp (mode, "r");
1455 /* Make sure the luser didn't pass "w" in. */
1456 if (!strcmp (mode, "w"))
1459 if (flags & LSTR_IGNORE_ACCESSIBLE)
1461 bmin = BUF_BEG (buf);
1466 bmin = BUF_BEGV (buf);
1467 bmax = BUF_ZV (buf);
1474 assert (bmin <= start);
1475 assert (start <= bmax);
1478 assert (bmin <= end);
1479 assert (end <= bmax);
1480 assert (start <= end);
1483 lstr = Lstream_new (lstream_lisp_buffer, mode);
1484 str = LISP_BUFFER_STREAM_DATA (lstr);
1489 XSETBUFFER (buffer, buf);
1490 marker = Fmake_marker ();
1491 Fset_marker (marker, make_int (start), buffer);
1492 str->start = marker;
1493 marker = Fmake_marker ();
1494 Fset_marker (marker, make_int (start), buffer);
1495 str->orig_start = marker;
1498 marker = Fmake_marker ();
1499 Fset_marker (marker, make_int (end), buffer);
1504 str->buffer = buffer;
1507 XSETLSTREAM (obj, lstr);
1512 make_lisp_buffer_input_stream (struct buffer *buf, Bufpos start, Bufpos end,
1515 return make_lisp_buffer_stream_1 (buf, start, end, flags, "r");
1519 make_lisp_buffer_output_stream (struct buffer *buf, Bufpos pos, int flags)
1521 Lisp_Object lstr = make_lisp_buffer_stream_1 (buf, pos, 0, flags, "wc");
1523 Lstream_set_character_mode (XLSTREAM (lstr));
1528 lisp_buffer_reader (Lstream *stream, unsigned char *data, size_t size)
1530 struct lisp_buffer_stream *str = LISP_BUFFER_STREAM_DATA (stream);
1531 unsigned char *orig_data = data;
1534 struct buffer *buf = XBUFFER (str->buffer);
1536 if (!BUFFER_LIVE_P (buf))
1537 return 0; /* Fut. */
1539 /* NOTE: We do all our operations in Bytind's.
1540 Keep in mind that SIZE is a value in bytes, not chars. */
1542 start = bi_marker_position (str->start);
1543 end = bi_marker_position (str->end);
1544 if (!(str->flags & LSTR_IGNORE_ACCESSIBLE))
1546 start = bytind_clip_to_bounds (BI_BUF_BEGV (buf), start,
1548 end = bytind_clip_to_bounds (BI_BUF_BEGV (buf), end,
1552 size = min (size, (size_t) (end - start));
1554 /* We cannot return a partial character. */
1555 VALIDATE_BYTIND_BACKWARD (buf, end);
1562 if (str->flags & LSTR_IGNORE_ACCESSIBLE)
1563 ceil = BI_BUF_CEILING_OF_IGNORE_ACCESSIBLE (buf, start);
1565 ceil = BI_BUF_CEILING_OF (buf, start);
1566 chunk = min (ceil, end) - start;
1567 memcpy (data, BI_BUF_BYTE_ADDRESS (buf, start), chunk);
1572 if (EQ (buf->selective_display, Qt) && str->flags & LSTR_SELECTIVE)
1574 /* What a kludge. What a kludge. What a kludge. */
1576 for (p = orig_data; p < data; p++)
1581 set_bi_marker_position (str->start, end);
1582 return data - orig_data;
1586 lisp_buffer_writer (Lstream *stream, CONST unsigned char *data, size_t size)
1588 struct lisp_buffer_stream *str = LISP_BUFFER_STREAM_DATA (stream);
1590 struct buffer *buf = XBUFFER (str->buffer);
1592 if (!BUFFER_LIVE_P (buf))
1593 return 0; /* Fut. */
1595 pos = marker_position (str->start);
1596 pos += buffer_insert_raw_string_1 (buf, pos, data, size, 0);
1597 set_marker_position (str->start, pos);
1602 lisp_buffer_rewinder (Lstream *stream)
1604 struct lisp_buffer_stream *str =
1605 LISP_BUFFER_STREAM_DATA (stream);
1606 struct buffer *buf = XBUFFER (str->buffer);
1607 long pos = marker_position (str->orig_start);
1608 if (!BUFFER_LIVE_P (buf))
1609 return -1; /* Fut. */
1610 if (pos > BUF_ZV (buf))
1612 if (pos < marker_position (str->orig_start))
1613 pos = marker_position (str->orig_start);
1614 if (MARKERP (str->end) && pos > marker_position (str->end))
1615 pos = marker_position (str->end);
1616 set_marker_position (str->start, pos);
1621 lisp_buffer_marker (Lisp_Object stream)
1623 struct lisp_buffer_stream *str =
1624 LISP_BUFFER_STREAM_DATA (XLSTREAM (stream));
1626 mark_object (str->start);
1627 mark_object (str->end);
1632 lisp_buffer_stream_startpos (Lstream *stream)
1634 return marker_position (LISP_BUFFER_STREAM_DATA (stream)->start);
1638 /************************************************************************/
1639 /* initialization */
1640 /************************************************************************/
1643 lstream_type_create (void)
1645 LSTREAM_HAS_METHOD (stdio, reader);
1646 LSTREAM_HAS_METHOD (stdio, writer);
1647 LSTREAM_HAS_METHOD (stdio, rewinder);
1648 LSTREAM_HAS_METHOD (stdio, seekable_p);
1649 LSTREAM_HAS_METHOD (stdio, flusher);
1650 LSTREAM_HAS_METHOD (stdio, closer);
1652 LSTREAM_HAS_METHOD (filedesc, reader);
1653 LSTREAM_HAS_METHOD (filedesc, writer);
1654 LSTREAM_HAS_METHOD (filedesc, was_blocked_p);
1655 LSTREAM_HAS_METHOD (filedesc, rewinder);
1656 LSTREAM_HAS_METHOD (filedesc, seekable_p);
1657 LSTREAM_HAS_METHOD (filedesc, closer);
1659 LSTREAM_HAS_METHOD (lisp_string, reader);
1660 LSTREAM_HAS_METHOD (lisp_string, rewinder);
1661 LSTREAM_HAS_METHOD (lisp_string, marker);
1663 LSTREAM_HAS_METHOD (fixed_buffer, reader);
1664 LSTREAM_HAS_METHOD (fixed_buffer, writer);
1665 LSTREAM_HAS_METHOD (fixed_buffer, rewinder);
1667 LSTREAM_HAS_METHOD (resizing_buffer, writer);
1668 LSTREAM_HAS_METHOD (resizing_buffer, rewinder);
1669 LSTREAM_HAS_METHOD (resizing_buffer, closer);
1671 LSTREAM_HAS_METHOD (dynarr, writer);
1672 LSTREAM_HAS_METHOD (dynarr, rewinder);
1673 LSTREAM_HAS_METHOD (dynarr, closer);
1675 LSTREAM_HAS_METHOD (lisp_buffer, reader);
1676 LSTREAM_HAS_METHOD (lisp_buffer, writer);
1677 LSTREAM_HAS_METHOD (lisp_buffer, rewinder);
1678 LSTREAM_HAS_METHOD (lisp_buffer, marker);
1682 reinit_vars_of_lstream (void)
1686 for (i = 0; i < countof (Vlstream_free_list); i++)
1688 Vlstream_free_list[i] = Qnil;
1689 staticpro_nodump (&Vlstream_free_list[i]);
1694 vars_of_lstream (void)
1696 reinit_vars_of_lstream ();