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 int 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 int 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, void (*markobj) (Lisp_Object))
139 Lstream *lstr = XLSTREAM (obj);
140 return lstr->imp->marker ? (lstr->imp->marker) (obj, markobj) : 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 int 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 >= (int) 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 int 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 < (int) size; i++)
484 if (Lstream_putc (lstr, p[i]) < 0)
487 return i == 0 ? -1 : 0;
491 Lstream_was_blocked_p (Lstream *lstr)
493 if (lstr->imp->was_blocked_p)
494 return (lstr->imp->was_blocked_p) (lstr);
500 Lstream_raw_read (Lstream *lstr, unsigned char *buffer, size_t size)
502 if (! (lstr->flags & LSTREAM_FL_IS_OPEN))
503 Lstream_internal_error ("lstream not open", lstr);
504 if (! (lstr->flags & LSTREAM_FL_READ))
505 Lstream_internal_error ("lstream not open for reading", lstr);
506 if (!lstr->imp->reader)
507 Lstream_internal_error ("lstream has no reader", lstr);
509 return (lstr->imp->reader) (lstr, buffer, size);
512 /* Assuming the buffer is empty, fill it up again. */
515 Lstream_read_more (Lstream *lstr)
518 int size_needed = max (1, min (MAX_READ_SIZE, lstr->buffering_size));
520 /* If someone requested a larger buffer size, so be it! */
521 int size_needed = max (1, lstr->buffering_size);
525 DO_REALLOC (lstr->in_buffer, lstr->in_buffer_size,
526 size_needed, unsigned char);
527 size_gotten = Lstream_raw_read (lstr, lstr->in_buffer, size_needed);
528 lstr->in_buffer_current = max (0, size_gotten);
529 lstr->in_buffer_ind = 0;
530 return size_gotten < 0 ? -1 : size_gotten;
534 Lstream_read (Lstream *lstr, void *data, size_t size)
536 unsigned char *p = (unsigned char *) data;
539 int error_occurred = 0;
544 /* First try to get some data from the unget buffer */
545 chunk = min (size, lstr->unget_buffer_ind);
548 /* The bytes come back in reverse order. */
549 for (; off < (int) chunk; off++)
550 p[off] = lstr->unget_buffer[--lstr->unget_buffer_ind];
551 lstr->byte_count += chunk;
557 /* Take whatever we can from the in buffer */
558 chunk = min (size, lstr->in_buffer_current - lstr->in_buffer_ind);
561 memcpy (p + off, lstr->in_buffer + lstr->in_buffer_ind, chunk);
562 lstr->in_buffer_ind += chunk;
563 lstr->byte_count += chunk;
568 /* If we need some more, try to get some more from the stream's end */
571 int retval = Lstream_read_more (lstr);
579 /* #### Beware of OFF ending up 0. */
580 if ((lstr->flags & LSTREAM_FL_NO_PARTIAL_CHARS) && off > 0)
582 /* It's quite possible for us to get passed an incomplete
583 character at the end. We need to spit back that
584 incomplete character. */
585 CONST unsigned char *dataend = p + off - 1;
586 /* Optimize the most common case. */
587 if (!BYTE_ASCII_P (*dataend))
589 /* Go back to the beginning of the last (and possibly partial)
590 character, and bump forward to see if the character is
592 VALIDATE_CHARPTR_BACKWARD (dataend);
593 if (dataend + REP_BYTES_BY_FIRST_BYTE (*dataend) != p + off)
595 int newoff = dataend - p;
596 /* If not, chop the size down to ignore the last char
597 and stash it away for next time. */
598 Lstream_unread (lstr, dataend, off - newoff);
604 return ((off == 0 && error_occurred) ? -1 : off);
608 Lstream_unread (Lstream *lstr, CONST void *data, size_t size)
611 unsigned char *p = (unsigned char *) data;
613 /* Make sure buffer is big enough */
615 DO_REALLOC (lstr->unget_buffer, lstr->unget_buffer_size,
616 lstr->unget_buffer_ind + size, unsigned char);
618 /* Bytes have to go on in reverse order -- they are reversed
619 again when read back. */
620 for (i = size - 1; i >= 0; i--)
621 lstr->unget_buffer[lstr->unget_buffer_ind++] = p[i];
622 lstr->byte_count -= size;
626 Lstream_rewind (Lstream *lstr)
628 if (!lstr->imp->rewinder)
629 Lstream_internal_error ("lstream has no rewinder", lstr);
630 if (Lstream_flush (lstr) < 0)
632 lstr->byte_count = 0;
633 return (lstr->imp->rewinder) (lstr);
637 Lstream_seekable_p (Lstream *lstr)
639 if (!lstr->imp->rewinder)
641 if (!lstr->imp->seekable_p)
643 return (lstr->imp->seekable_p) (lstr);
647 Lstream_pseudo_close (Lstream *lstr)
651 if (!lstr->flags & LSTREAM_FL_IS_OPEN)
652 Lstream_internal_error ("lstream is not open", lstr);
654 /* don't check errors here -- best not to risk file descriptor loss */
655 rc = Lstream_flush (lstr);
661 Lstream_close (Lstream *lstr)
665 if (lstr->flags & LSTREAM_FL_IS_OPEN)
667 rc = Lstream_pseudo_close (lstr);
669 * We used to return immediately if the closer method reported
670 * failure, leaving the stream open. But this is no good, for
671 * the following reasons.
673 * 1. The finalizer method used in GC makes no provision for
674 * failure, so we must not return without freeing buffer
677 * 2. The closer method may have already freed some memory
678 * used for I/O in this stream. E.g. encoding_closer frees
679 * ENCODING_STREAM_DATA(stream)->runoff. If a writer method
680 * tries to use this buffer later, it will write into memory
681 * that may have been allocated elsewhere. Sometime later
682 * you will see a sign that says "Welcome to Crash City."
684 * 3. The closer can report failure if a flush fails in the
685 * other stream in a MULE encoding/decoding stream pair.
686 * The other stream in the pair is closed, but returning
687 * early leaves the current stream open. If we try to
688 * flush the current stream later, we will crash when the
689 * flusher notices that the other end stream is closed.
691 * So, we no longer abort the close if the closer method
692 * reports some kind of failure. We still report the failure
695 if (lstr->imp->closer)
696 if ((lstr->imp->closer) (lstr) < 0)
700 lstr->flags &= ~LSTREAM_FL_IS_OPEN;
701 lstr->byte_count = 0;
702 /* Note that Lstream_flush() reset all the buffer indices. That way,
703 the next call to Lstream_putc(), Lstream_getc(), or Lstream_ungetc()
704 on a closed stream will call into the function equivalents, which will
707 /* We set the pointers to 0 so that we don't lose when this function
708 is called more than once on the same object */
709 if (lstr->out_buffer)
711 xfree (lstr->out_buffer);
712 lstr->out_buffer = 0;
716 xfree (lstr->in_buffer);
719 if (lstr->unget_buffer)
721 xfree (lstr->unget_buffer);
722 lstr->unget_buffer = 0;
729 Lstream_fputc (Lstream *lstr, int c)
731 unsigned char ch = (unsigned char) c;
732 int retval = Lstream_write_1 (lstr, &ch, 1);
733 if (retval >= 0 && lstr->buffering == LSTREAM_LINE_BUFFERED && ch == '\n')
734 return Lstream_flush_out (lstr);
735 return retval < 0 ? -1 : 0;
739 Lstream_fgetc (Lstream *lstr)
742 if (Lstream_read (lstr, &ch, 1) <= 0)
748 Lstream_fungetc (Lstream *lstr, int c)
750 unsigned char ch = (unsigned char) c;
751 Lstream_unread (lstr, &ch, 1);
755 /************************ some stream implementations *********************/
757 /*********** a stdio stream ***********/
765 #define STDIO_STREAM_DATA(stream) LSTREAM_TYPE_DATA (stream, stdio)
767 DEFINE_LSTREAM_IMPLEMENTATION ("stdio", lstream_stdio,
768 sizeof (struct stdio_stream));
771 make_stdio_stream_1 (FILE *stream, int flags, CONST char *mode)
774 Lstream *lstr = Lstream_new (lstream_stdio, mode);
775 struct stdio_stream *str = STDIO_STREAM_DATA (lstr);
777 str->closing = flags & LSTR_CLOSING;
778 lstr->flags |= LSTREAM_FL_CLOSE_AT_DISKSAVE;
779 XSETLSTREAM (obj, lstr);
784 make_stdio_input_stream (FILE *stream, int flags)
786 return make_stdio_stream_1 (stream, flags, "r");
790 make_stdio_output_stream (FILE *stream, int flags)
792 return make_stdio_stream_1 (stream, flags, "w");
796 stdio_reader (Lstream *stream, unsigned char *data, size_t size)
798 struct stdio_stream *str = STDIO_STREAM_DATA (stream);
799 size_t val = fread (data, 1, (size_t) size, str->file);
800 if (!val && ferror (str->file))
806 stdio_writer (Lstream *stream, CONST unsigned char *data, size_t size)
808 struct stdio_stream *str = STDIO_STREAM_DATA (stream);
809 size_t val = fwrite (data, 1, size, str->file);
810 if (!val && ferror (str->file))
816 stdio_rewinder (Lstream *stream)
818 rewind (STDIO_STREAM_DATA (stream)->file);
823 stdio_seekable_p (Lstream *stream)
826 struct stdio_stream *str = STDIO_STREAM_DATA (stream);
828 if (fstat (fileno (str->file), &lestat) < 0)
830 return S_ISREG (lestat.st_mode);
834 stdio_flusher (Lstream *stream)
836 struct stdio_stream *str = STDIO_STREAM_DATA (stream);
837 if (stream->flags & LSTREAM_FL_WRITE)
838 return fflush (str->file);
840 /* call fpurge? Only exists on some systems. #### Why not add a
841 configure check for HAVE_FPURGE and utilize it on systems that
842 support it? --hniksic */
847 stdio_closer (Lstream *stream)
849 struct stdio_stream *str = STDIO_STREAM_DATA (stream);
851 return fclose (str->file);
853 if (stream->flags & LSTREAM_FL_WRITE)
854 return fflush (str->file);
856 /* call fpurge? Only exists on some systems. */
860 /*********** a file descriptor ***********/
862 struct filedesc_stream
870 int chars_sans_newline;
871 unsigned int closing :1;
872 unsigned int allow_quit :1;
873 unsigned int blocked_ok :1;
874 unsigned int pty_flushing :1;
875 unsigned int blocking_error_p :1;
878 #define FILEDESC_STREAM_DATA(stream) LSTREAM_TYPE_DATA (stream, filedesc)
880 DEFINE_LSTREAM_IMPLEMENTATION ("filedesc", lstream_filedesc,
881 sizeof (struct filedesc_stream));
883 /* Make a stream that reads from or writes to a file descriptor FILEDESC.
884 OFFSET is the offset from the *current* file pointer that the reading
885 should start at. COUNT is the number of bytes to be read (it is
886 ignored when writing); -1 for unlimited. */
888 make_filedesc_stream_1 (int filedesc, int offset, int count, int flags,
892 Lstream *lstr = Lstream_new (lstream_filedesc, mode);
893 struct filedesc_stream *fstr = FILEDESC_STREAM_DATA (lstr);
895 fstr->closing = !!(flags & LSTR_CLOSING);
896 fstr->allow_quit = !!(flags & LSTR_ALLOW_QUIT);
897 fstr->blocked_ok = !!(flags & LSTR_BLOCKED_OK);
898 fstr->pty_flushing = !!(flags & LSTR_PTY_FLUSHING);
899 fstr->blocking_error_p = 0;
900 fstr->chars_sans_newline = 0;
901 fstr->starting_pos = lseek (filedesc, offset, SEEK_CUR);
902 fstr->current_pos = max (fstr->starting_pos, 0);
906 fstr->end_pos = fstr->starting_pos + count;
907 lstr->flags |= LSTREAM_FL_CLOSE_AT_DISKSAVE;
908 XSETLSTREAM (obj, lstr);
913 make_filedesc_input_stream (int filedesc, int offset, int count, int flags)
915 return make_filedesc_stream_1 (filedesc, offset, count, flags, "r");
919 make_filedesc_output_stream (int filedesc, int offset, int count, int flags)
921 return make_filedesc_stream_1 (filedesc, offset, count, flags, "w");
925 filedesc_reader (Lstream *stream, unsigned char *data, size_t size)
928 struct filedesc_stream *str = FILEDESC_STREAM_DATA (stream);
929 if (str->end_pos >= 0)
930 size = min (size, (size_t) (str->end_pos - str->current_pos));
931 nread = (str->allow_quit ? read_allowing_quit : read) (str->fd, data, size);
933 str->current_pos += nread;
938 errno_would_block_p (int val)
941 if (val == EWOULDBLOCK)
952 filedesc_writer (Lstream *stream, CONST unsigned char *data, size_t size)
954 struct filedesc_stream *str = FILEDESC_STREAM_DATA (stream);
956 int need_newline = 0;
958 /* This function would be simple if it were not for the blasted
959 PTY max-bytes stuff. Why the hell can't they just have written
960 the PTY drivers right so this problem doesn't exist?
962 Maybe all the PTY crap here should be moved into another stream
963 that does nothing but periodically insert EOF's as necessary. */
964 if (str->pty_flushing)
966 /* To make life easy, only send out one line at the most. */
967 CONST unsigned char *ptr;
969 ptr = (CONST unsigned char *) memchr (data, '\n', size);
974 if (ptr - data >= str->pty_max_bytes - str->chars_sans_newline)
976 ptr = data + str->pty_max_bytes - str->chars_sans_newline;
982 /**** start of non-PTY-crap ****/
984 retval = ((str->allow_quit ? write_allowing_quit : write)
985 (str->fd, data, size));
988 if (retval < 0 && errno_would_block_p (errno) && str->blocked_ok)
990 str->blocking_error_p = 1;
993 str->blocking_error_p = 0;
996 /**** end non-PTY-crap ****/
998 if (str->pty_flushing)
1000 str->chars_sans_newline += retval;
1001 /* Note that a newline was not among the bytes written out.
1002 Add to the number of non-newline bytes written out,
1003 and flush with an EOF if necessary. Be careful to
1004 keep track of write errors as we go along and look
1005 out for EWOULDBLOCK. */
1006 if (str->chars_sans_newline >= str->pty_max_bytes)
1008 int retval2 = ((str->allow_quit ? write_allowing_quit : write)
1009 (str->fd, &str->eof_char, 1));
1011 str->chars_sans_newline = 0;
1012 else if (retval2 < 0)
1014 /* Error writing the EOF char. If nothing got written,
1015 then treat this as an error -- either return an error
1016 condition or set the blocking-error flag. */
1019 if (errno_would_block_p (errno) && str->blocked_ok)
1021 str->blocking_error_p = 1;
1033 /* The need_newline flag is necessary because otherwise when the
1034 first byte is a newline, we'd get stuck never writing anything
1035 in pty-flushing mode. */
1039 int retval2 = ((str->allow_quit ? write_allowing_quit : write)
1043 str->chars_sans_newline = 0;
1046 else if (retval2 < 0)
1048 /* Error writing the newline char. If nothing got written,
1049 then treat this as an error -- either return an error
1050 condition or set the blocking-error flag. */
1053 if (errno_would_block_p (errno) && str->blocked_ok)
1055 str->blocking_error_p = 1;
1070 filedesc_rewinder (Lstream *stream)
1072 struct filedesc_stream *str = FILEDESC_STREAM_DATA (stream);
1073 if (str->starting_pos < 0 ||
1074 lseek (FILEDESC_STREAM_DATA (stream)->fd, str->starting_pos,
1079 str->current_pos = str->starting_pos;
1085 filedesc_seekable_p (Lstream *stream)
1087 struct filedesc_stream *str = FILEDESC_STREAM_DATA (stream);
1088 if (str->starting_pos < 0)
1094 if (fstat (str->fd, &lestat) < 0)
1096 return S_ISREG (lestat.st_mode);
1101 filedesc_closer (Lstream *stream)
1103 struct filedesc_stream *str = FILEDESC_STREAM_DATA (stream);
1105 return close (str->fd);
1111 filedesc_was_blocked_p (Lstream *stream)
1113 struct filedesc_stream *str = FILEDESC_STREAM_DATA (stream);
1114 return str->blocking_error_p;
1118 filedesc_stream_set_pty_flushing (Lstream *stream, int pty_max_bytes,
1121 struct filedesc_stream *str = FILEDESC_STREAM_DATA (stream);
1122 str->pty_max_bytes = pty_max_bytes;
1123 str->eof_char = eof_char;
1124 str->pty_flushing = 1;
1128 filedesc_stream_fd (Lstream *stream)
1130 struct filedesc_stream *str = FILEDESC_STREAM_DATA (stream);
1134 /*********** read from a Lisp string ***********/
1136 #define LISP_STRING_STREAM_DATA(stream) LSTREAM_TYPE_DATA (stream, lisp_string)
1138 struct lisp_string_stream
1141 Bytecount init_offset;
1142 Bytecount offset, end;
1145 DEFINE_LSTREAM_IMPLEMENTATION ("lisp-string", lstream_lisp_string,
1146 sizeof (struct lisp_string_stream));
1149 make_lisp_string_input_stream (Lisp_Object string, Bytecount offset,
1154 struct lisp_string_stream *str;
1156 CHECK_STRING (string);
1158 len = XSTRING_LENGTH (string) - offset;
1159 assert (offset >= 0);
1161 assert (offset + len <= XSTRING_LENGTH (string));
1163 lstr = Lstream_new (lstream_lisp_string, "r");
1164 str = LISP_STRING_STREAM_DATA (lstr);
1165 str->offset = offset;
1166 str->end = offset + len;
1167 str->init_offset = offset;
1169 XSETLSTREAM (obj, lstr);
1174 lisp_string_reader (Lstream *stream, unsigned char *data, size_t size)
1176 struct lisp_string_stream *str = LISP_STRING_STREAM_DATA (stream);
1177 /* Don't lose if the string shrank past us ... */
1178 Bytecount offset = min (str->offset, XSTRING_LENGTH (str->obj));
1179 Bufbyte *strstart = XSTRING_DATA (str->obj);
1180 Bufbyte *start = strstart + offset;
1182 /* ... or if someone changed the string and we ended up in the
1183 middle of a character. */
1184 /* Being in the middle of a character is `normal' unless
1185 LSTREAM_NO_PARTIAL_CHARS - mrb */
1186 if (stream->flags & LSTREAM_FL_NO_PARTIAL_CHARS)
1187 VALIDATE_CHARPTR_BACKWARD (start);
1188 offset = start - strstart;
1189 size = min (size, (size_t) (str->end - offset));
1190 memcpy (data, start, size);
1191 str->offset = offset + size;
1196 lisp_string_rewinder (Lstream *stream)
1198 struct lisp_string_stream *str = LISP_STRING_STREAM_DATA (stream);
1199 int pos = str->init_offset;
1202 /* Don't lose if the string shrank past us ... */
1203 pos = min (pos, XSTRING_LENGTH (str->obj));
1204 /* ... or if someone changed the string and we ended up in the
1205 middle of a character. */
1207 Bufbyte *strstart = XSTRING_DATA (str->obj);
1208 Bufbyte *start = strstart + pos;
1209 VALIDATE_CHARPTR_BACKWARD (start);
1210 pos = start - strstart;
1217 lisp_string_marker (Lisp_Object stream, void (*markobj) (Lisp_Object))
1219 struct lisp_string_stream *str = LISP_STRING_STREAM_DATA (XLSTREAM (stream));
1223 /*********** a fixed buffer ***********/
1225 #define FIXED_BUFFER_STREAM_DATA(stream) \
1226 LSTREAM_TYPE_DATA (stream, fixed_buffer)
1228 struct fixed_buffer_stream
1230 CONST unsigned char *inbuf;
1231 unsigned char *outbuf;
1236 DEFINE_LSTREAM_IMPLEMENTATION ("fixed-buffer", lstream_fixed_buffer,
1237 sizeof (struct fixed_buffer_stream));
1240 make_fixed_buffer_input_stream (CONST unsigned char *buf, size_t size)
1243 Lstream *lstr = Lstream_new (lstream_fixed_buffer, "r");
1244 struct fixed_buffer_stream *str = FIXED_BUFFER_STREAM_DATA (lstr);
1247 XSETLSTREAM (obj, lstr);
1252 make_fixed_buffer_output_stream (unsigned char *buf, size_t size)
1255 Lstream *lstr = Lstream_new (lstream_fixed_buffer, "w");
1256 struct fixed_buffer_stream *str = FIXED_BUFFER_STREAM_DATA (lstr);
1259 XSETLSTREAM (obj, lstr);
1264 fixed_buffer_reader (Lstream *stream, unsigned char *data, size_t size)
1266 struct fixed_buffer_stream *str = FIXED_BUFFER_STREAM_DATA (stream);
1267 size = min (size, str->size - str->offset);
1268 memcpy (data, str->inbuf + str->offset, size);
1269 str->offset += size;
1274 fixed_buffer_writer (Lstream *stream, CONST unsigned char *data, size_t size)
1276 struct fixed_buffer_stream *str = FIXED_BUFFER_STREAM_DATA (stream);
1277 if (str->offset == str->size)
1279 /* If we're at the end, just throw away the data and pretend
1280 we wrote all of it. If we return 0, then the lstream routines
1281 will try again and again to write it out. */
1284 size = min (size, str->size - str->offset);
1285 memcpy (str->outbuf + str->offset, data, size);
1286 str->offset += size;
1291 fixed_buffer_rewinder (Lstream *stream)
1293 FIXED_BUFFER_STREAM_DATA (stream)->offset = 0;
1297 CONST unsigned char *
1298 fixed_buffer_input_stream_ptr (Lstream *stream)
1300 assert (stream->imp == lstream_fixed_buffer);
1301 return FIXED_BUFFER_STREAM_DATA (stream)->inbuf;
1305 fixed_buffer_output_stream_ptr (Lstream *stream)
1307 assert (stream->imp == lstream_fixed_buffer);
1308 return FIXED_BUFFER_STREAM_DATA (stream)->outbuf;
1311 /*********** write to a resizing buffer ***********/
1313 #define RESIZING_BUFFER_STREAM_DATA(stream) \
1314 LSTREAM_TYPE_DATA (stream, resizing_buffer)
1316 struct resizing_buffer_stream
1324 DEFINE_LSTREAM_IMPLEMENTATION ("resizing-buffer", lstream_resizing_buffer,
1325 sizeof (struct resizing_buffer_stream));
1328 make_resizing_buffer_output_stream (void)
1331 XSETLSTREAM (obj, Lstream_new (lstream_resizing_buffer, "w"));
1336 resizing_buffer_writer (Lstream *stream, CONST unsigned char *data, size_t size)
1338 struct resizing_buffer_stream *str = RESIZING_BUFFER_STREAM_DATA (stream);
1339 DO_REALLOC (str->buf, str->allocked, str->stored + size, unsigned char);
1340 memcpy (str->buf + str->stored, data, size);
1341 str->stored += size;
1342 str->max_stored = max (str->max_stored, str->stored);
1347 resizing_buffer_rewinder (Lstream *stream)
1349 RESIZING_BUFFER_STREAM_DATA (stream)->stored = 0;
1354 resizing_buffer_closer (Lstream *stream)
1356 struct resizing_buffer_stream *str = RESIZING_BUFFER_STREAM_DATA (stream);
1366 resizing_buffer_stream_ptr (Lstream *stream)
1368 return RESIZING_BUFFER_STREAM_DATA (stream)->buf;
1371 /*********** write to an unsigned-char dynarr ***********/
1373 /* Note: If you have a dynarr whose type is not unsigned_char_dynarr
1374 but which is really just an unsigned_char_dynarr (e.g. its type
1375 is Bufbyte or Extbyte), just cast to unsigned_char_dynarr. */
1377 #define DYNARR_STREAM_DATA(stream) \
1378 LSTREAM_TYPE_DATA (stream, dynarr)
1380 struct dynarr_stream
1382 unsigned_char_dynarr *dyn;
1385 DEFINE_LSTREAM_IMPLEMENTATION ("dynarr", lstream_dynarr,
1386 sizeof (struct dynarr_stream));
1389 make_dynarr_output_stream (unsigned_char_dynarr *dyn)
1392 XSETLSTREAM (obj, Lstream_new (lstream_dynarr, "w"));
1393 DYNARR_STREAM_DATA (XLSTREAM (obj))->dyn = dyn;
1398 dynarr_writer (Lstream *stream, CONST unsigned char *data, size_t size)
1400 struct dynarr_stream *str = DYNARR_STREAM_DATA (stream);
1401 Dynarr_add_many (str->dyn, data, size);
1406 dynarr_rewinder (Lstream *stream)
1408 Dynarr_reset (DYNARR_STREAM_DATA (stream)->dyn);
1413 dynarr_closer (Lstream *stream)
1418 /************ read from or write to a Lisp buffer ************/
1420 /* Note: Lisp-buffer read streams never return partial characters,
1421 and Lisp-buffer write streams expect to never get partial
1424 #define LISP_BUFFER_STREAM_DATA(stream) \
1425 LSTREAM_TYPE_DATA (stream, lisp_buffer)
1427 struct lisp_buffer_stream
1430 Lisp_Object orig_start;
1431 /* we use markers to properly deal with insertion/deletion */
1432 Lisp_Object start, end;
1436 DEFINE_LSTREAM_IMPLEMENTATION ("lisp-buffer", lstream_lisp_buffer,
1437 sizeof (struct lisp_buffer_stream));
1440 make_lisp_buffer_stream_1 (struct buffer *buf, Bufpos start, Bufpos end,
1441 int flags, CONST char *mode)
1445 struct lisp_buffer_stream *str;
1447 int reading = !strcmp (mode, "r");
1449 /* Make sure the luser didn't pass "w" in. */
1450 if (!strcmp (mode, "w"))
1453 if (flags & LSTR_IGNORE_ACCESSIBLE)
1455 bmin = BUF_BEG (buf);
1460 bmin = BUF_BEGV (buf);
1461 bmax = BUF_ZV (buf);
1468 assert (bmin <= start);
1469 assert (start <= bmax);
1472 assert (bmin <= end);
1473 assert (end <= bmax);
1474 assert (start <= end);
1477 lstr = Lstream_new (lstream_lisp_buffer, mode);
1478 str = LISP_BUFFER_STREAM_DATA (lstr);
1483 XSETBUFFER (buffer, buf);
1484 marker = Fmake_marker ();
1485 Fset_marker (marker, make_int (start), buffer);
1486 str->start = marker;
1487 marker = Fmake_marker ();
1488 Fset_marker (marker, make_int (start), buffer);
1489 str->orig_start = marker;
1492 marker = Fmake_marker ();
1493 Fset_marker (marker, make_int (end), buffer);
1498 str->buffer = buffer;
1501 XSETLSTREAM (obj, lstr);
1506 make_lisp_buffer_input_stream (struct buffer *buf, Bufpos start, Bufpos end,
1509 return make_lisp_buffer_stream_1 (buf, start, end, flags, "r");
1513 make_lisp_buffer_output_stream (struct buffer *buf, Bufpos pos, int flags)
1515 Lisp_Object lstr = make_lisp_buffer_stream_1 (buf, pos, 0, flags, "wc");
1517 Lstream_set_character_mode (XLSTREAM (lstr));
1522 lisp_buffer_reader (Lstream *stream, unsigned char *data, size_t size)
1524 struct lisp_buffer_stream *str = LISP_BUFFER_STREAM_DATA (stream);
1525 unsigned char *orig_data = data;
1528 struct buffer *buf = XBUFFER (str->buffer);
1530 if (!BUFFER_LIVE_P (buf))
1531 return 0; /* Fut. */
1533 /* NOTE: We do all our operations in Bytind's.
1534 Keep in mind that SIZE is a value in bytes, not chars. */
1536 start = bi_marker_position (str->start);
1537 end = bi_marker_position (str->end);
1538 if (!(str->flags & LSTR_IGNORE_ACCESSIBLE))
1540 start = bytind_clip_to_bounds (BI_BUF_BEGV (buf), start,
1542 end = bytind_clip_to_bounds (BI_BUF_BEGV (buf), end,
1546 size = min (size, (size_t) (end - start));
1548 /* We cannot return a partial character. */
1549 VALIDATE_BYTIND_BACKWARD (buf, end);
1556 if (str->flags & LSTR_IGNORE_ACCESSIBLE)
1557 ceil = BI_BUF_CEILING_OF_IGNORE_ACCESSIBLE (buf, start);
1559 ceil = BI_BUF_CEILING_OF (buf, start);
1560 chunk = min (ceil, end) - start;
1561 memcpy (data, BI_BUF_BYTE_ADDRESS (buf, start), chunk);
1566 if (EQ (buf->selective_display, Qt) && str->flags & LSTR_SELECTIVE)
1568 /* What a kludge. What a kludge. What a kludge. */
1570 for (p = orig_data; p < data; p++)
1575 set_bi_marker_position (str->start, end);
1576 return data - orig_data;
1580 lisp_buffer_writer (Lstream *stream, CONST unsigned char *data, size_t size)
1582 struct lisp_buffer_stream *str = LISP_BUFFER_STREAM_DATA (stream);
1584 struct buffer *buf = XBUFFER (str->buffer);
1586 if (!BUFFER_LIVE_P (buf))
1587 return 0; /* Fut. */
1589 pos = marker_position (str->start);
1590 pos += buffer_insert_raw_string_1 (buf, pos, data, size, 0);
1591 set_marker_position (str->start, pos);
1596 lisp_buffer_rewinder (Lstream *stream)
1598 struct lisp_buffer_stream *str =
1599 LISP_BUFFER_STREAM_DATA (stream);
1600 struct buffer *buf = XBUFFER (str->buffer);
1601 long pos = marker_position (str->orig_start);
1602 if (!BUFFER_LIVE_P (buf))
1603 return -1; /* Fut. */
1604 if (pos > BUF_ZV (buf))
1606 if (pos < marker_position (str->orig_start))
1607 pos = marker_position (str->orig_start);
1608 if (MARKERP (str->end) && pos > marker_position (str->end))
1609 pos = marker_position (str->end);
1610 set_marker_position (str->start, pos);
1615 lisp_buffer_marker (Lisp_Object stream, void (*markobj) (Lisp_Object))
1617 struct lisp_buffer_stream *str =
1618 LISP_BUFFER_STREAM_DATA (XLSTREAM (stream));
1620 markobj (str->start);
1626 lisp_buffer_stream_startpos (Lstream *stream)
1628 return marker_position (LISP_BUFFER_STREAM_DATA (stream)->start);
1632 /************************************************************************/
1633 /* initialization */
1634 /************************************************************************/
1637 lstream_type_create (void)
1639 LSTREAM_HAS_METHOD (stdio, reader);
1640 LSTREAM_HAS_METHOD (stdio, writer);
1641 LSTREAM_HAS_METHOD (stdio, rewinder);
1642 LSTREAM_HAS_METHOD (stdio, seekable_p);
1643 LSTREAM_HAS_METHOD (stdio, flusher);
1644 LSTREAM_HAS_METHOD (stdio, closer);
1646 LSTREAM_HAS_METHOD (filedesc, reader);
1647 LSTREAM_HAS_METHOD (filedesc, writer);
1648 LSTREAM_HAS_METHOD (filedesc, was_blocked_p);
1649 LSTREAM_HAS_METHOD (filedesc, rewinder);
1650 LSTREAM_HAS_METHOD (filedesc, seekable_p);
1651 LSTREAM_HAS_METHOD (filedesc, closer);
1653 LSTREAM_HAS_METHOD (lisp_string, reader);
1654 LSTREAM_HAS_METHOD (lisp_string, rewinder);
1655 LSTREAM_HAS_METHOD (lisp_string, marker);
1657 LSTREAM_HAS_METHOD (fixed_buffer, reader);
1658 LSTREAM_HAS_METHOD (fixed_buffer, writer);
1659 LSTREAM_HAS_METHOD (fixed_buffer, rewinder);
1661 LSTREAM_HAS_METHOD (resizing_buffer, writer);
1662 LSTREAM_HAS_METHOD (resizing_buffer, rewinder);
1663 LSTREAM_HAS_METHOD (resizing_buffer, closer);
1665 LSTREAM_HAS_METHOD (dynarr, writer);
1666 LSTREAM_HAS_METHOD (dynarr, rewinder);
1667 LSTREAM_HAS_METHOD (dynarr, closer);
1669 LSTREAM_HAS_METHOD (lisp_buffer, reader);
1670 LSTREAM_HAS_METHOD (lisp_buffer, writer);
1671 LSTREAM_HAS_METHOD (lisp_buffer, rewinder);
1672 LSTREAM_HAS_METHOD (lisp_buffer, marker);
1676 vars_of_lstream (void)
1680 for (i = 0; i < countof (Vlstream_free_list); i++)
1682 Vlstream_free_list[i] = Qnil;
1683 staticpro (&Vlstream_free_list[i]);