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. */
37 /* This function provides a generic buffering stream implementation.
38 Conceptually, you send data to the stream or read data from the
39 stream, not caring what's on the other end of the stream. The
40 other end could be another stream, a file descriptor, a stdio
41 stream, a fixed block of memory, a reallocating block of memory,
42 etc. The main purpose of the stream is to provide a standard
43 interface and to do buffering. Macros are defined to read
44 or write characters, so the calling functions do not have to
45 worry about blocking data together in order to achieve efficiency.
48 /* Note that this object is called "stream" in Lisp but "lstream"
49 in C. The reason for this is that "stream" is too generic a name
50 for C; too much likelihood of conflict/confusion with C++, etc. */
52 /* Functions are as follows:
54 Lstream *Lstream_new (Lstream_implementation *imp, const char *mode)
55 Allocate and return a new Lstream. This function is not
56 really meant to be called directly; rather, each stream type
57 should provide its own stream creation function, which
58 creates the stream and does any other necessary creation
59 stuff (e.g. opening a file).
61 void Lstream_set_buffering (Lstream *lstr, Lstream_buffering buffering,
63 Change the buffering of a stream. See lstream.h. By default
64 the buffering is STREAM_BLOCK_BUFFERED.
66 int Lstream_flush (Lstream *lstr)
67 Flush out any pending unwritten data in the stream. Clear
68 any buffered input data. Returns 0 on success, -1 on error.
70 int Lstream_putc (Lstream *stream, int c)
71 Write out one byte to the stream. This is a macro and so
72 it is very efficient. The C argument is only evaluated once
73 but the STREAM argument is evaluated more than once. Returns
74 0 on success, -1 on error.
76 int Lstream_getc (Lstream *stream)
77 Read one byte from the stream. This is a macro and so it
78 is very efficient. The STREAM argument is evaluated more
79 than once. Return value is -1 for EOF or error.
81 void Lstream_ungetc (Lstream *stream, int c)
82 Push one byte back onto the input queue. This will be the
83 next byte read from the stream. Any number of bytes can be
84 pushed back and will be read in the reverse order they were
85 pushed back -- most recent first. (This is necessary for
86 consistency -- if there are a number of bytes that have been
87 unread and I read and unread a byte, it needs to be the first
88 to be read again.) This is a macro and so it is very
89 efficient. The C argument is only evaluated once but the
90 STREAM argument is evaluated more than once.
92 int Lstream_fputc (Lstream *stream, int c)
93 int Lstream_fgetc (Lstream *stream)
94 void Lstream_fungetc (Lstream *stream, int c)
95 Function equivalents of the above macros.
97 ssize_t Lstream_read (Lstream *stream, void *data, size_t size)
98 Read SIZE bytes of DATA from the stream. Return the number of
99 bytes read. 0 means EOF. -1 means an error occurred and no
102 ssize_t Lstream_write (Lstream *stream, void *data, size_t size)
103 Write SIZE bytes of DATA to the stream. Return the number of
104 bytes written. -1 means an error occurred and no bytes were
107 void Lstream_unread (Lstream *stream, void *data, size_t size)
108 Push back SIZE bytes of DATA onto the input queue. The
109 next call to Lstream_read() with the same size will read the
110 same bytes back. Note that this will be the case even if
111 there is other pending unread data.
113 int Lstream_delete (Lstream *stream)
114 Frees all memory associated with the stream is freed. Calling
115 this is not strictly necessary, but it is much more efficient
116 than having the Lstream be garbage-collected.
118 int Lstream_close (Lstream *stream)
119 Close the stream. All data will be flushed out.
121 void Lstream_reopen (Lstream *stream)
122 Reopen a closed stream. This enables I/O on it again.
123 This is not meant to be called except from a wrapper routine
124 that reinitializes variables and such -- the close routine
125 may well have freed some necessary storage structures, for
128 void Lstream_rewind (Lstream *stream)
129 Rewind the stream to the beginning.
132 #define DEFAULT_BLOCK_BUFFERING_SIZE 512
133 #define MAX_READ_SIZE 512
136 mark_lstream (Lisp_Object obj)
138 Lstream *lstr = XLSTREAM (obj);
139 return lstr->imp->marker ? (lstr->imp->marker) (obj) : Qnil;
143 print_lstream (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag)
145 Lstream *lstr = XLSTREAM (obj);
148 sprintf (buf, "#<INTERNAL OBJECT (XEmacs bug?) (%s lstream) 0x%lx>",
149 lstr->imp->name, (long) lstr);
150 write_c_string (buf, printcharfun);
154 finalize_lstream (void *header, int for_disksave)
156 /* WARNING WARNING WARNING. This function (and all finalize functions)
157 may get called more than once on the same object, and may get called
158 (at dump time) on objects that are not being released. */
159 Lstream *lstr = (Lstream *) header;
161 #if 0 /* this may cause weird Broken Pipes? */
164 Lstream_pseudo_close (lstr);
168 if (lstr->flags & LSTREAM_FL_IS_OPEN)
172 if (lstr->flags & LSTREAM_FL_CLOSE_AT_DISKSAVE)
173 Lstream_close (lstr);
177 Lstream_close (lstr);
182 sizeof_lstream (const void *header)
184 const Lstream *lstr = (const Lstream *) header;
185 return sizeof (*lstr) + lstr->imp->size - 1;
188 DEFINE_LRECORD_SEQUENCE_IMPLEMENTATION ("stream", lstream,
189 mark_lstream, print_lstream,
190 finalize_lstream, 0, 0, 0,
191 sizeof_lstream, Lstream);
194 Lstream_set_buffering (Lstream *lstr, Lstream_buffering buffering,
197 lstr->buffering = buffering;
200 case LSTREAM_UNBUFFERED:
201 lstr->buffering_size = 0; break;
202 case LSTREAM_BLOCK_BUFFERED:
203 lstr->buffering_size = DEFAULT_BLOCK_BUFFERING_SIZE; break;
204 case LSTREAM_BLOCKN_BUFFERED:
205 lstr->buffering_size = buffering_size; break;
206 case LSTREAM_LINE_BUFFERED:
207 case LSTREAM_UNLIMITED:
208 lstr->buffering_size = INT_MAX; break;
212 static const Lstream_implementation *lstream_types[32];
213 static Lisp_Object Vlstream_free_list[32];
214 static int lstream_type_count;
217 Lstream_new (const Lstream_implementation *imp, const char *mode)
222 for (i = 0; i < lstream_type_count; i++)
224 if (lstream_types[i] == imp)
228 if (i == lstream_type_count)
230 assert (lstream_type_count < countof (lstream_types));
231 lstream_types[lstream_type_count] = imp;
232 Vlstream_free_list[lstream_type_count] =
233 make_lcrecord_list (sizeof (*p) + imp->size - 1,
235 lstream_type_count++;
238 p = XLSTREAM (allocate_managed_lcrecord (Vlstream_free_list[i]));
239 /* Zero it out, except the header. */
240 memset ((char *) p + sizeof (p->header), 0,
241 sizeof (*p) - sizeof (p->header) + imp->size - 1);
243 Lstream_set_buffering (p, LSTREAM_BLOCK_BUFFERED, 0);
244 p->flags = LSTREAM_FL_IS_OPEN;
246 /* convert mode (one of "r", "w", "rc", "wc") to p->flags */
247 assert (mode[0] == 'r' || mode[0] == 'w');
248 assert (mode[1] == 'c' || mode[1] == '\0');
249 p->flags |= (mode[0] == 'r' ? LSTREAM_FL_READ : LSTREAM_FL_WRITE);
251 p->flags |= LSTREAM_FL_NO_PARTIAL_CHARS;
257 Lstream_set_character_mode (Lstream *lstr)
259 lstr->flags |= LSTREAM_FL_NO_PARTIAL_CHARS;
263 Lstream_delete (Lstream *lstr)
268 XSETLSTREAM (val, lstr);
269 for (i = 0; i < lstream_type_count; i++)
271 if (lstream_types[i] == lstr->imp)
273 free_managed_lcrecord (Vlstream_free_list[i], val);
281 #define Lstream_internal_error(reason, lstr) \
282 Lstream_signal_simple_error ("Internal error: " reason, lstr)
284 static void Lstream_signal_simple_error (const char *reason, Lstream *lstr)
287 XSETLSTREAM (obj, lstr);
288 signal_simple_error (reason, obj);
292 Lstream_reopen (Lstream *lstr)
294 if (lstr->flags & LSTREAM_FL_IS_OPEN)
295 Lstream_internal_error ("lstream already open", lstr);
296 lstr->flags |= LSTREAM_FL_IS_OPEN;
299 /* Attempt to flush out all of the buffered data for writing. */
302 Lstream_flush_out (Lstream *lstr)
306 while (lstr->out_buffer_ind > 0)
308 size_t size = lstr->out_buffer_ind;
309 if (! (lstr->flags & LSTREAM_FL_IS_OPEN))
310 Lstream_internal_error ("lstream not open", lstr);
311 if (! (lstr->flags & LSTREAM_FL_WRITE))
312 Lstream_internal_error ("lstream not open for writing", lstr);
313 if (!lstr->imp->writer)
314 Lstream_internal_error ("lstream has no writer", lstr);
316 if (lstr->flags & LSTREAM_FL_NO_PARTIAL_CHARS)
317 /* It's quite possible for us to get passed an incomplete
318 character at the end. We need to spit back that
319 incomplete character. */
321 const unsigned char *data = lstr->out_buffer;
322 const unsigned char *dataend = data + size - 1;
323 assert (size > 0); /* safety check ... */
324 /* Optimize the most common case. */
325 if (!BYTE_ASCII_P (*dataend))
327 /* Go back to the beginning of the last (and possibly partial)
328 character, and bump forward to see if the character is
330 VALIDATE_CHARPTR_BACKWARD (dataend);
331 if (dataend + REP_BYTES_BY_FIRST_BYTE (*dataend) != data + size)
332 /* If not, chop the size down to ignore the last char
333 and stash it away for next time. */
334 size = dataend - data;
335 /* If we don't even have one character to write, then just
342 num_written = (lstr->imp->writer) (lstr, lstr->out_buffer, size);
343 if (num_written == 0)
344 /* If nothing got written, then just hold the data. This may
345 occur, for example, if this stream does non-blocking I/O;
346 the attempt to write the data might have resulted in an
347 EWOULDBLOCK error. */
349 else if (num_written >= lstr->out_buffer_ind)
350 lstr->out_buffer_ind = 0;
351 else if (num_written > 0)
353 memmove (lstr->out_buffer, lstr->out_buffer + num_written,
354 lstr->out_buffer_ind - num_written);
355 lstr->out_buffer_ind -= num_written;
358 /* If error, just hold the data, for similar reasons as above. */
362 if (lstr->imp->flusher)
363 return (lstr->imp->flusher) (lstr);
369 Lstream_flush (Lstream *lstr)
371 if (Lstream_flush_out (lstr) < 0)
374 /* clear out buffered data */
375 lstr->in_buffer_current = lstr->in_buffer_ind = 0;
376 lstr->unget_buffer_ind = 0;
381 /* We want to add NUM characters. This function ensures that the
382 buffer is large enough for this (per the buffering size specified
383 in the stream) and returns the number of characters we can
384 actually write. If FORCE is set, ignore the buffering size
385 and go ahead and make space for all the chars even if it exceeds
386 the buffering size. (This is used to deal with the possibility
387 that the stream writer might refuse to write any bytes now, e.g.
388 if it's getting EWOULDBLOCK errors. We have to keep stocking them
389 up until they can be written, so as to avoid losing data. */
392 Lstream_adding (Lstream *lstr, size_t num, int force)
394 size_t size = num + lstr->out_buffer_ind;
396 if (size <= lstr->out_buffer_size)
399 /* Maybe chop it down so that we don't buffer more characters
400 than our advertised buffering size. */
401 if ((size > lstr->buffering_size) && !force)
403 size = lstr->buffering_size;
404 /* There might be more data buffered than the buffering size. */
405 if (size <= lstr->out_buffer_ind)
409 DO_REALLOC (lstr->out_buffer, lstr->out_buffer_size, size, unsigned char);
411 return size - lstr->out_buffer_ind;
414 /* Like Lstream_write(), but does not handle line-buffering correctly. */
417 Lstream_write_1 (Lstream *lstr, const void *data, size_t size)
419 const unsigned char *p = (const unsigned char *) data;
421 if (! (lstr->flags & LSTREAM_FL_IS_OPEN))
422 Lstream_internal_error ("lstream not open", lstr);
423 if (! (lstr->flags & LSTREAM_FL_WRITE))
424 Lstream_internal_error ("lstream not open for writing", lstr);
426 int couldnt_write_last_time = 0;
430 /* Figure out how much we can add to the buffer */
431 size_t chunk = Lstream_adding (lstr, size, 0);
434 if (couldnt_write_last_time)
435 /* Ung, we ran out of space and tried to flush
436 the buffer, but it didn't work because the stream
437 writer is refusing to accept any data. So we
438 just have to squirrel away all the rest of the
440 chunk = Lstream_adding (lstr, size, 1);
442 couldnt_write_last_time = 1;
447 memcpy (lstr->out_buffer + lstr->out_buffer_ind, p + off, chunk);
448 lstr->out_buffer_ind += chunk;
449 lstr->byte_count += chunk;
453 /* If the buffer is full and we have more to add, flush it out. */
456 if (Lstream_flush_out (lstr) < 0)
471 /* If the stream is not line-buffered, then we can just call
472 Lstream_write_1(), which writes in chunks. Otherwise, we
473 repeatedly call Lstream_putc(), which knows how to handle
474 line buffering. Returns number of bytes written. */
477 Lstream_write (Lstream *lstr, const void *data, size_t size)
480 const unsigned char *p = (const unsigned char *) data;
484 if (lstr->buffering != LSTREAM_LINE_BUFFERED)
485 return Lstream_write_1 (lstr, data, size);
486 for (i = 0; i < size; i++)
488 if (Lstream_putc (lstr, p[i]) < 0)
491 return i == 0 ? -1 : (ssize_t) i;
495 Lstream_was_blocked_p (Lstream *lstr)
497 return lstr->imp->was_blocked_p ? lstr->imp->was_blocked_p (lstr) : 0;
501 Lstream_raw_read (Lstream *lstr, unsigned char *buffer, size_t size)
503 if (! (lstr->flags & LSTREAM_FL_IS_OPEN))
504 Lstream_internal_error ("lstream not open", lstr);
505 if (! (lstr->flags & LSTREAM_FL_READ))
506 Lstream_internal_error ("lstream not open for reading", lstr);
507 if (!lstr->imp->reader)
508 Lstream_internal_error ("lstream has no reader", lstr);
510 return (lstr->imp->reader) (lstr, buffer, size);
513 /* Assuming the buffer is empty, fill it up again. */
516 Lstream_read_more (Lstream *lstr)
519 ssize_t size_needed = max (1, min (MAX_READ_SIZE, lstr->buffering_size));
521 /* If someone requested a larger buffer size, so be it! */
522 ssize_t size_needed = max (1, lstr->buffering_size);
526 DO_REALLOC (lstr->in_buffer, lstr->in_buffer_size,
527 size_needed, unsigned char);
528 size_gotten = Lstream_raw_read (lstr, lstr->in_buffer, size_needed);
529 lstr->in_buffer_current = max (0, size_gotten);
530 lstr->in_buffer_ind = 0;
531 return size_gotten < 0 ? -1 : size_gotten;
535 Lstream_read (Lstream *lstr, void *data, size_t size)
537 unsigned char *p = (unsigned char *) data;
540 int error_occurred = 0;
545 /* First try to get some data from the unget buffer */
546 chunk = min (size, lstr->unget_buffer_ind);
549 /* The bytes come back in reverse order. */
550 for (; off < chunk; off++)
551 p[off] = lstr->unget_buffer[--lstr->unget_buffer_ind];
552 lstr->byte_count += chunk;
558 /* Take whatever we can from the in buffer */
559 chunk = min (size, lstr->in_buffer_current - lstr->in_buffer_ind);
562 memcpy (p + off, lstr->in_buffer + lstr->in_buffer_ind, chunk);
563 lstr->in_buffer_ind += chunk;
564 lstr->byte_count += chunk;
569 /* If we need some more, try to get some more from the stream's end */
572 ssize_t retval = Lstream_read_more (lstr);
580 /* #### Beware of OFF ending up 0. */
581 if ((lstr->flags & LSTREAM_FL_NO_PARTIAL_CHARS) && off > 0)
583 /* It's quite possible for us to get passed an incomplete
584 character at the end. We need to spit back that
585 incomplete character. */
586 const unsigned char *dataend = p + off - 1;
587 /* Optimize the most common case. */
588 if (!BYTE_ASCII_P (*dataend))
590 /* Go back to the beginning of the last (and possibly partial)
591 character, and bump forward to see if the character is
593 VALIDATE_CHARPTR_BACKWARD (dataend);
594 if (dataend + REP_BYTES_BY_FIRST_BYTE (*dataend) != p + off)
596 size_t newoff = dataend - p;
597 /* If not, chop the size down to ignore the last char
598 and stash it away for next time. */
599 Lstream_unread (lstr, dataend, off - newoff);
605 return off == 0 && error_occurred ? -1 : (ssize_t) off;
609 Lstream_unread (Lstream *lstr, const void *data, size_t size)
611 const unsigned char *p = (const unsigned char *) data;
613 /* Make sure buffer is big enough */
614 DO_REALLOC (lstr->unget_buffer, lstr->unget_buffer_size,
615 lstr->unget_buffer_ind + size, unsigned char);
617 lstr->byte_count -= size;
619 /* Bytes have to go on in reverse order -- they are reversed
620 again when read back. */
622 lstr->unget_buffer[lstr->unget_buffer_ind++] = p[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)
649 if (!lstr->flags & LSTREAM_FL_IS_OPEN)
650 Lstream_internal_error ("lstream is not open", lstr);
652 /* don't check errors here -- best not to risk file descriptor loss */
653 return Lstream_flush (lstr);
657 Lstream_close (Lstream *lstr)
661 if (lstr->flags & LSTREAM_FL_IS_OPEN)
663 rc = Lstream_pseudo_close (lstr);
665 * We used to return immediately if the closer method reported
666 * failure, leaving the stream open. But this is no good, for
667 * the following reasons.
669 * 1. The finalizer method used in GC makes no provision for
670 * failure, so we must not return without freeing buffer
673 * 2. The closer method may have already freed some memory
674 * used for I/O in this stream. E.g. encoding_closer frees
675 * ENCODING_STREAM_DATA(stream)->runoff. If a writer method
676 * tries to use this buffer later, it will write into memory
677 * that may have been allocated elsewhere. Sometime later
678 * you will see a sign that says "Welcome to Crash City."
680 * 3. The closer can report failure if a flush fails in the
681 * other stream in a MULE encoding/decoding stream pair.
682 * The other stream in the pair is closed, but returning
683 * early leaves the current stream open. If we try to
684 * flush the current stream later, we will crash when the
685 * flusher notices that the other end stream is closed.
687 * So, we no longer abort the close if the closer method
688 * reports some kind of failure. We still report the failure
691 if (lstr->imp->closer)
692 if ((lstr->imp->closer) (lstr) < 0)
696 lstr->flags &= ~LSTREAM_FL_IS_OPEN;
697 lstr->byte_count = 0;
698 /* Note that Lstream_flush() reset all the buffer indices. That way,
699 the next call to Lstream_putc(), Lstream_getc(), or Lstream_ungetc()
700 on a closed stream will call into the function equivalents, which will
703 /* We set the pointers to 0 so that we don't lose when this function
704 is called more than once on the same object */
705 if (lstr->out_buffer)
707 xfree (lstr->out_buffer);
708 lstr->out_buffer = 0;
712 xfree (lstr->in_buffer);
715 if (lstr->unget_buffer)
717 xfree (lstr->unget_buffer);
718 lstr->unget_buffer = 0;
725 Lstream_fputc (Lstream *lstr, int c)
727 unsigned char ch = (unsigned char) c;
728 ssize_t retval = Lstream_write_1 (lstr, &ch, 1);
729 if (retval >= 0 && lstr->buffering == LSTREAM_LINE_BUFFERED && ch == '\n')
730 return Lstream_flush_out (lstr);
731 return retval < 0 ? -1 : 0;
735 Lstream_fgetc (Lstream *lstr)
738 if (Lstream_read (lstr, &ch, 1) <= 0)
744 Lstream_fungetc (Lstream *lstr, int c)
746 unsigned char ch = (unsigned char) c;
747 Lstream_unread (lstr, &ch, 1);
751 /************************ some stream implementations *********************/
753 /*********** a stdio stream ***********/
761 #define STDIO_STREAM_DATA(stream) LSTREAM_TYPE_DATA (stream, stdio)
763 DEFINE_LSTREAM_IMPLEMENTATION ("stdio", lstream_stdio,
764 sizeof (struct stdio_stream));
767 make_stdio_stream_1 (FILE *stream, int flags, const char *mode)
770 Lstream *lstr = Lstream_new (lstream_stdio, mode);
771 struct stdio_stream *str = STDIO_STREAM_DATA (lstr);
773 str->closing = flags & LSTR_CLOSING;
774 lstr->flags |= LSTREAM_FL_CLOSE_AT_DISKSAVE;
775 XSETLSTREAM (obj, lstr);
780 make_stdio_input_stream (FILE *stream, int flags)
782 return make_stdio_stream_1 (stream, flags, "r");
786 make_stdio_output_stream (FILE *stream, int flags)
788 return make_stdio_stream_1 (stream, flags, "w");
791 /* #### From reading the Unix 98 specification, it appears that if we
792 want stdio_reader() to be completely correct, we should check for
793 0 < val < size and if so, check to see if an error has occurred.
794 If an error has occurred, but val is non-zero, we should go ahead
795 and act as if the read was successful, but remember in some fashion
796 or other, that an error has occurred, and report that on the next
797 call to stdio_reader instead of calling fread() again.
799 Currently, in such a case, we end up calling fread() twice and we
802 1) this is not harmful, and
803 2) the error will still be reported on the second read.
805 This is probably reasonable, so I don't think we should change this
806 code (it could even be argued that the error might have fixed
807 itself, so we should do the fread() again. */
810 stdio_reader (Lstream *stream, unsigned char *data, size_t size)
812 struct stdio_stream *str = STDIO_STREAM_DATA (stream);
813 size_t val = fread (data, 1, size, str->file);
814 if (!val && ferror (str->file))
820 stdio_writer (Lstream *stream, const unsigned char *data, size_t size)
822 struct stdio_stream *str = STDIO_STREAM_DATA (stream);
823 size_t val = fwrite (data, 1, size, str->file);
824 if (!val && ferror (str->file))
830 stdio_rewinder (Lstream *stream)
832 rewind (STDIO_STREAM_DATA (stream)->file);
837 stdio_seekable_p (Lstream *stream)
840 struct stdio_stream *str = STDIO_STREAM_DATA (stream);
842 if (fstat (fileno (str->file), &lestat) < 0)
844 return S_ISREG (lestat.st_mode);
848 stdio_flusher (Lstream *stream)
850 struct stdio_stream *str = STDIO_STREAM_DATA (stream);
851 if (stream->flags & LSTREAM_FL_WRITE)
852 return fflush (str->file);
858 stdio_closer (Lstream *stream)
860 struct stdio_stream *str = STDIO_STREAM_DATA (stream);
862 return fclose (str->file);
864 if (stream->flags & LSTREAM_FL_WRITE)
865 return fflush (str->file);
870 /*********** a file descriptor ***********/
872 struct filedesc_stream
880 int chars_sans_newline;
881 unsigned int closing :1;
882 unsigned int allow_quit :1;
883 unsigned int blocked_ok :1;
884 unsigned int pty_flushing :1;
885 unsigned int blocking_error_p :1;
888 #define FILEDESC_STREAM_DATA(stream) LSTREAM_TYPE_DATA (stream, filedesc)
890 DEFINE_LSTREAM_IMPLEMENTATION ("filedesc", lstream_filedesc,
891 sizeof (struct filedesc_stream));
893 /* Make a stream that reads from or writes to a file descriptor FILEDESC.
894 OFFSET is the offset from the *current* file pointer that the reading
895 should start at. COUNT is the number of bytes to be read (it is
896 ignored when writing); -1 for unlimited. */
898 make_filedesc_stream_1 (int filedesc, int offset, int count, int flags,
902 Lstream *lstr = Lstream_new (lstream_filedesc, mode);
903 struct filedesc_stream *fstr = FILEDESC_STREAM_DATA (lstr);
905 fstr->closing = !!(flags & LSTR_CLOSING);
906 fstr->allow_quit = !!(flags & LSTR_ALLOW_QUIT);
907 fstr->blocked_ok = !!(flags & LSTR_BLOCKED_OK);
908 fstr->pty_flushing = !!(flags & LSTR_PTY_FLUSHING);
909 fstr->blocking_error_p = 0;
910 fstr->chars_sans_newline = 0;
911 fstr->starting_pos = lseek (filedesc, offset, SEEK_CUR);
912 fstr->current_pos = max (fstr->starting_pos, 0);
916 fstr->end_pos = fstr->starting_pos + count;
917 lstr->flags |= LSTREAM_FL_CLOSE_AT_DISKSAVE;
918 XSETLSTREAM (obj, lstr);
923 make_filedesc_input_stream (int filedesc, int offset, int count, int flags)
925 return make_filedesc_stream_1 (filedesc, offset, count, flags, "r");
929 make_filedesc_output_stream (int filedesc, int offset, int count, int flags)
931 return make_filedesc_stream_1 (filedesc, offset, count, flags, "w");
935 filedesc_reader (Lstream *stream, unsigned char *data, size_t size)
938 struct filedesc_stream *str = FILEDESC_STREAM_DATA (stream);
939 if (str->end_pos >= 0)
940 size = min (size, (size_t) (str->end_pos - str->current_pos));
941 nread = str->allow_quit ?
942 read_allowing_quit (str->fd, data, size) :
943 read (str->fd, data, size);
945 str->current_pos += nread;
950 errno_would_block_p (int val)
953 if (val == EWOULDBLOCK)
964 filedesc_writer (Lstream *stream, const unsigned char *data, size_t size)
966 struct filedesc_stream *str = FILEDESC_STREAM_DATA (stream);
968 int need_newline = 0;
970 /* This function would be simple if it were not for the blasted
971 PTY max-bytes stuff. Why the hell can't they just have written
972 the PTY drivers right so this problem doesn't exist?
974 Maybe all the PTY crap here should be moved into another stream
975 that does nothing but periodically insert EOF's as necessary. */
976 if (str->pty_flushing)
978 /* To make life easy, only send out one line at the most. */
979 const unsigned char *ptr;
981 ptr = (const unsigned char *) memchr (data, '\n', size);
986 if (ptr - data >= str->pty_max_bytes - str->chars_sans_newline)
988 ptr = data + str->pty_max_bytes - str->chars_sans_newline;
994 /**** start of non-PTY-crap ****/
996 retval = str->allow_quit ?
997 write_allowing_quit (str->fd, data, size) :
998 write (str->fd, data, size);
1001 if (retval < 0 && errno_would_block_p (errno) && str->blocked_ok)
1003 str->blocking_error_p = 1;
1006 str->blocking_error_p = 0;
1009 /**** end non-PTY-crap ****/
1011 if (str->pty_flushing)
1013 str->chars_sans_newline += retval;
1014 /* Note that a newline was not among the bytes written out.
1015 Add to the number of non-newline bytes written out,
1016 and flush with an EOF if necessary. Be careful to
1017 keep track of write errors as we go along and look
1018 out for EWOULDBLOCK. */
1019 if (str->chars_sans_newline >= str->pty_max_bytes)
1021 ssize_t retval2 = str->allow_quit ?
1022 write_allowing_quit (str->fd, &str->eof_char, 1) :
1023 write (str->fd, &str->eof_char, 1);
1026 str->chars_sans_newline = 0;
1027 else if (retval2 < 0)
1029 /* Error writing the EOF char. If nothing got written,
1030 then treat this as an error -- either return an error
1031 condition or set the blocking-error flag. */
1034 if (errno_would_block_p (errno) && str->blocked_ok)
1036 str->blocking_error_p = 1;
1048 /* The need_newline flag is necessary because otherwise when the
1049 first byte is a newline, we'd get stuck never writing anything
1050 in pty-flushing mode. */
1054 ssize_t retval2 = str->allow_quit ?
1055 write_allowing_quit (str->fd, &nl, 1) :
1056 write (str->fd, &nl, 1);
1060 str->chars_sans_newline = 0;
1063 else if (retval2 < 0)
1065 /* Error writing the newline char. If nothing got written,
1066 then treat this as an error -- either return an error
1067 condition or set the blocking-error flag. */
1070 if (errno_would_block_p (errno) && str->blocked_ok)
1072 str->blocking_error_p = 1;
1087 filedesc_rewinder (Lstream *stream)
1089 struct filedesc_stream *str = FILEDESC_STREAM_DATA (stream);
1090 if (str->starting_pos < 0 ||
1091 lseek (FILEDESC_STREAM_DATA (stream)->fd, str->starting_pos,
1096 str->current_pos = str->starting_pos;
1102 filedesc_seekable_p (Lstream *stream)
1104 struct filedesc_stream *str = FILEDESC_STREAM_DATA (stream);
1105 if (str->starting_pos < 0)
1111 if (fstat (str->fd, &lestat) < 0)
1113 return S_ISREG (lestat.st_mode);
1118 filedesc_closer (Lstream *stream)
1120 struct filedesc_stream *str = FILEDESC_STREAM_DATA (stream);
1122 return close (str->fd);
1128 filedesc_was_blocked_p (Lstream *stream)
1130 struct filedesc_stream *str = FILEDESC_STREAM_DATA (stream);
1131 return str->blocking_error_p;
1135 filedesc_stream_set_pty_flushing (Lstream *stream, int pty_max_bytes,
1138 struct filedesc_stream *str = FILEDESC_STREAM_DATA (stream);
1139 str->pty_max_bytes = pty_max_bytes;
1140 str->eof_char = eof_char;
1141 str->pty_flushing = 1;
1145 filedesc_stream_fd (Lstream *stream)
1147 struct filedesc_stream *str = FILEDESC_STREAM_DATA (stream);
1151 /*********** read from a Lisp string ***********/
1153 #define LISP_STRING_STREAM_DATA(stream) LSTREAM_TYPE_DATA (stream, lisp_string)
1155 struct lisp_string_stream
1158 Bytecount init_offset;
1159 Bytecount offset, end;
1162 DEFINE_LSTREAM_IMPLEMENTATION ("lisp-string", lstream_lisp_string,
1163 sizeof (struct lisp_string_stream));
1166 make_lisp_string_input_stream (Lisp_Object string, Bytecount offset,
1171 struct lisp_string_stream *str;
1173 CHECK_STRING (string);
1175 len = XSTRING_LENGTH (string) - offset;
1176 assert (offset >= 0);
1178 assert (offset + len <= XSTRING_LENGTH (string));
1180 lstr = Lstream_new (lstream_lisp_string, "r");
1181 str = LISP_STRING_STREAM_DATA (lstr);
1182 str->offset = offset;
1183 str->end = offset + len;
1184 str->init_offset = offset;
1186 XSETLSTREAM (obj, lstr);
1191 lisp_string_reader (Lstream *stream, unsigned char *data, size_t size)
1193 struct lisp_string_stream *str = LISP_STRING_STREAM_DATA (stream);
1194 /* Don't lose if the string shrank past us ... */
1195 Bytecount offset = min (str->offset, XSTRING_LENGTH (str->obj));
1196 Bufbyte *strstart = XSTRING_DATA (str->obj);
1197 Bufbyte *start = strstart + offset;
1199 /* ... or if someone changed the string and we ended up in the
1200 middle of a character. */
1201 /* Being in the middle of a character is `normal' unless
1202 LSTREAM_NO_PARTIAL_CHARS - mrb */
1203 if (stream->flags & LSTREAM_FL_NO_PARTIAL_CHARS)
1204 VALIDATE_CHARPTR_BACKWARD (start);
1205 offset = start - strstart;
1206 size = min (size, (size_t) (str->end - offset));
1207 memcpy (data, start, size);
1208 str->offset = offset + size;
1213 lisp_string_rewinder (Lstream *stream)
1215 struct lisp_string_stream *str = LISP_STRING_STREAM_DATA (stream);
1216 int pos = str->init_offset;
1219 /* Don't lose if the string shrank past us ... */
1220 pos = min (pos, XSTRING_LENGTH (str->obj));
1221 /* ... or if someone changed the string and we ended up in the
1222 middle of a character. */
1224 Bufbyte *strstart = XSTRING_DATA (str->obj);
1225 Bufbyte *start = strstart + pos;
1226 VALIDATE_CHARPTR_BACKWARD (start);
1227 pos = start - strstart;
1234 lisp_string_marker (Lisp_Object stream)
1236 struct lisp_string_stream *str = LISP_STRING_STREAM_DATA (XLSTREAM (stream));
1240 /*********** a fixed buffer ***********/
1242 #define FIXED_BUFFER_STREAM_DATA(stream) \
1243 LSTREAM_TYPE_DATA (stream, fixed_buffer)
1245 struct fixed_buffer_stream
1247 const unsigned char *inbuf;
1248 unsigned char *outbuf;
1253 DEFINE_LSTREAM_IMPLEMENTATION ("fixed-buffer", lstream_fixed_buffer,
1254 sizeof (struct fixed_buffer_stream));
1257 make_fixed_buffer_input_stream (const void *buf, size_t size)
1260 Lstream *lstr = Lstream_new (lstream_fixed_buffer, "r");
1261 struct fixed_buffer_stream *str = FIXED_BUFFER_STREAM_DATA (lstr);
1262 str->inbuf = (const unsigned char *) buf;
1264 XSETLSTREAM (obj, lstr);
1269 make_fixed_buffer_output_stream (void *buf, size_t size)
1272 Lstream *lstr = Lstream_new (lstream_fixed_buffer, "w");
1273 struct fixed_buffer_stream *str = FIXED_BUFFER_STREAM_DATA (lstr);
1274 str->outbuf = (unsigned char *) buf;
1276 XSETLSTREAM (obj, lstr);
1281 fixed_buffer_reader (Lstream *stream, unsigned char *data, size_t size)
1283 struct fixed_buffer_stream *str = FIXED_BUFFER_STREAM_DATA (stream);
1284 size = min (size, str->size - str->offset);
1285 memcpy (data, str->inbuf + str->offset, size);
1286 str->offset += size;
1291 fixed_buffer_writer (Lstream *stream, const unsigned char *data, size_t size)
1293 struct fixed_buffer_stream *str = FIXED_BUFFER_STREAM_DATA (stream);
1294 if (str->offset == str->size)
1296 /* If we're at the end, just throw away the data and pretend
1297 we wrote all of it. If we return 0, then the lstream routines
1298 will try again and again to write it out. */
1301 size = min (size, str->size - str->offset);
1302 memcpy (str->outbuf + str->offset, data, size);
1303 str->offset += size;
1308 fixed_buffer_rewinder (Lstream *stream)
1310 FIXED_BUFFER_STREAM_DATA (stream)->offset = 0;
1314 const unsigned char *
1315 fixed_buffer_input_stream_ptr (Lstream *stream)
1317 assert (stream->imp == lstream_fixed_buffer);
1318 return FIXED_BUFFER_STREAM_DATA (stream)->inbuf;
1322 fixed_buffer_output_stream_ptr (Lstream *stream)
1324 assert (stream->imp == lstream_fixed_buffer);
1325 return FIXED_BUFFER_STREAM_DATA (stream)->outbuf;
1328 /*********** write to a resizing buffer ***********/
1330 #define RESIZING_BUFFER_STREAM_DATA(stream) \
1331 LSTREAM_TYPE_DATA (stream, resizing_buffer)
1333 struct resizing_buffer_stream
1341 DEFINE_LSTREAM_IMPLEMENTATION ("resizing-buffer", lstream_resizing_buffer,
1342 sizeof (struct resizing_buffer_stream));
1345 make_resizing_buffer_output_stream (void)
1348 XSETLSTREAM (obj, Lstream_new (lstream_resizing_buffer, "w"));
1353 resizing_buffer_writer (Lstream *stream, const unsigned char *data, size_t size)
1355 struct resizing_buffer_stream *str = RESIZING_BUFFER_STREAM_DATA (stream);
1356 DO_REALLOC (str->buf, str->allocked, str->stored + size, unsigned char);
1357 memcpy (str->buf + str->stored, data, size);
1358 str->stored += size;
1359 str->max_stored = max (str->max_stored, str->stored);
1364 resizing_buffer_rewinder (Lstream *stream)
1366 RESIZING_BUFFER_STREAM_DATA (stream)->stored = 0;
1371 resizing_buffer_closer (Lstream *stream)
1373 struct resizing_buffer_stream *str = RESIZING_BUFFER_STREAM_DATA (stream);
1383 resizing_buffer_stream_ptr (Lstream *stream)
1385 return RESIZING_BUFFER_STREAM_DATA (stream)->buf;
1388 /*********** write to an unsigned-char dynarr ***********/
1390 /* Note: If you have a dynarr whose type is not unsigned_char_dynarr
1391 but which is really just an unsigned_char_dynarr (e.g. its type
1392 is Bufbyte or Extbyte), just cast to unsigned_char_dynarr. */
1394 #define DYNARR_STREAM_DATA(stream) \
1395 LSTREAM_TYPE_DATA (stream, dynarr)
1397 struct dynarr_stream
1399 unsigned_char_dynarr *dyn;
1402 DEFINE_LSTREAM_IMPLEMENTATION ("dynarr", lstream_dynarr,
1403 sizeof (struct dynarr_stream));
1406 make_dynarr_output_stream (unsigned_char_dynarr *dyn)
1409 XSETLSTREAM (obj, Lstream_new (lstream_dynarr, "w"));
1410 DYNARR_STREAM_DATA (XLSTREAM (obj))->dyn = dyn;
1415 dynarr_writer (Lstream *stream, const unsigned char *data, size_t size)
1417 struct dynarr_stream *str = DYNARR_STREAM_DATA (stream);
1418 Dynarr_add_many (str->dyn, data, size);
1423 dynarr_rewinder (Lstream *stream)
1425 Dynarr_reset (DYNARR_STREAM_DATA (stream)->dyn);
1430 dynarr_closer (Lstream *stream)
1435 /************ read from or write to a Lisp buffer ************/
1437 /* Note: Lisp-buffer read streams never return partial characters,
1438 and Lisp-buffer write streams expect to never get partial
1441 #define LISP_BUFFER_STREAM_DATA(stream) \
1442 LSTREAM_TYPE_DATA (stream, lisp_buffer)
1444 struct lisp_buffer_stream
1447 Lisp_Object orig_start;
1448 /* we use markers to properly deal with insertion/deletion */
1449 Lisp_Object start, end;
1453 DEFINE_LSTREAM_IMPLEMENTATION ("lisp-buffer", lstream_lisp_buffer,
1454 sizeof (struct lisp_buffer_stream));
1457 make_lisp_buffer_stream_1 (struct buffer *buf, Bufpos start, Bufpos end,
1458 int flags, const char *mode)
1462 struct lisp_buffer_stream *str;
1464 int reading = !strcmp (mode, "r");
1466 /* Make sure the luser didn't pass "w" in. */
1467 if (!strcmp (mode, "w"))
1470 if (flags & LSTR_IGNORE_ACCESSIBLE)
1472 bmin = BUF_BEG (buf);
1477 bmin = BUF_BEGV (buf);
1478 bmax = BUF_ZV (buf);
1485 assert (bmin <= start);
1486 assert (start <= bmax);
1489 assert (bmin <= end);
1490 assert (end <= bmax);
1491 assert (start <= end);
1494 lstr = Lstream_new (lstream_lisp_buffer, mode);
1495 str = LISP_BUFFER_STREAM_DATA (lstr);
1500 XSETBUFFER (buffer, buf);
1501 marker = Fmake_marker ();
1502 Fset_marker (marker, make_int (start), buffer);
1503 str->start = marker;
1504 marker = Fmake_marker ();
1505 Fset_marker (marker, make_int (start), buffer);
1506 str->orig_start = marker;
1509 marker = Fmake_marker ();
1510 Fset_marker (marker, make_int (end), buffer);
1515 str->buffer = buffer;
1518 XSETLSTREAM (obj, lstr);
1523 make_lisp_buffer_input_stream (struct buffer *buf, Bufpos start, Bufpos end,
1526 return make_lisp_buffer_stream_1 (buf, start, end, flags, "r");
1530 make_lisp_buffer_output_stream (struct buffer *buf, Bufpos pos, int flags)
1532 Lisp_Object lstr = make_lisp_buffer_stream_1 (buf, pos, 0, flags, "wc");
1534 Lstream_set_character_mode (XLSTREAM (lstr));
1539 lisp_buffer_reader (Lstream *stream, unsigned char *data, size_t size)
1541 struct lisp_buffer_stream *str = LISP_BUFFER_STREAM_DATA (stream);
1542 unsigned char *orig_data = data;
1545 struct buffer *buf = XBUFFER (str->buffer);
1547 if (!BUFFER_LIVE_P (buf))
1548 return 0; /* Fut. */
1550 /* NOTE: We do all our operations in Bytind's.
1551 Keep in mind that SIZE is a value in bytes, not chars. */
1553 start = bi_marker_position (str->start);
1554 end = bi_marker_position (str->end);
1555 if (!(str->flags & LSTR_IGNORE_ACCESSIBLE))
1557 start = bytind_clip_to_bounds (BI_BUF_BEGV (buf), start,
1559 end = bytind_clip_to_bounds (BI_BUF_BEGV (buf), end,
1563 size = min (size, (size_t) (end - start));
1565 /* We cannot return a partial character. */
1566 VALIDATE_BYTIND_BACKWARD (buf, end);
1573 if (str->flags & LSTR_IGNORE_ACCESSIBLE)
1574 ceil = BI_BUF_CEILING_OF_IGNORE_ACCESSIBLE (buf, start);
1576 ceil = BI_BUF_CEILING_OF (buf, start);
1577 chunk = min (ceil, end) - start;
1578 memcpy (data, BI_BUF_BYTE_ADDRESS (buf, start), chunk);
1583 if (EQ (buf->selective_display, Qt) && str->flags & LSTR_SELECTIVE)
1585 /* What a kludge. What a kludge. What a kludge. */
1587 for (p = orig_data; p < data; p++)
1592 set_bi_marker_position (str->start, end);
1593 return data - orig_data;
1597 lisp_buffer_writer (Lstream *stream, const unsigned char *data, size_t size)
1599 struct lisp_buffer_stream *str = LISP_BUFFER_STREAM_DATA (stream);
1601 struct buffer *buf = XBUFFER (str->buffer);
1603 if (!BUFFER_LIVE_P (buf))
1604 return 0; /* Fut. */
1606 pos = marker_position (str->start);
1607 pos += buffer_insert_raw_string_1 (buf, pos, data, size, 0);
1608 set_marker_position (str->start, pos);
1613 lisp_buffer_rewinder (Lstream *stream)
1615 struct lisp_buffer_stream *str =
1616 LISP_BUFFER_STREAM_DATA (stream);
1617 struct buffer *buf = XBUFFER (str->buffer);
1618 long pos = marker_position (str->orig_start);
1619 if (!BUFFER_LIVE_P (buf))
1620 return -1; /* Fut. */
1621 if (pos > BUF_ZV (buf))
1623 if (pos < marker_position (str->orig_start))
1624 pos = marker_position (str->orig_start);
1625 if (MARKERP (str->end) && pos > marker_position (str->end))
1626 pos = marker_position (str->end);
1627 set_marker_position (str->start, pos);
1632 lisp_buffer_marker (Lisp_Object stream)
1634 struct lisp_buffer_stream *str =
1635 LISP_BUFFER_STREAM_DATA (XLSTREAM (stream));
1637 mark_object (str->start);
1638 mark_object (str->end);
1643 lisp_buffer_stream_startpos (Lstream *stream)
1645 return marker_position (LISP_BUFFER_STREAM_DATA (stream)->start);
1649 /************************************************************************/
1650 /* initialization */
1651 /************************************************************************/
1654 lstream_type_create (void)
1656 LSTREAM_HAS_METHOD (stdio, reader);
1657 LSTREAM_HAS_METHOD (stdio, writer);
1658 LSTREAM_HAS_METHOD (stdio, rewinder);
1659 LSTREAM_HAS_METHOD (stdio, seekable_p);
1660 LSTREAM_HAS_METHOD (stdio, flusher);
1661 LSTREAM_HAS_METHOD (stdio, closer);
1663 LSTREAM_HAS_METHOD (filedesc, reader);
1664 LSTREAM_HAS_METHOD (filedesc, writer);
1665 LSTREAM_HAS_METHOD (filedesc, was_blocked_p);
1666 LSTREAM_HAS_METHOD (filedesc, rewinder);
1667 LSTREAM_HAS_METHOD (filedesc, seekable_p);
1668 LSTREAM_HAS_METHOD (filedesc, closer);
1670 LSTREAM_HAS_METHOD (lisp_string, reader);
1671 LSTREAM_HAS_METHOD (lisp_string, rewinder);
1672 LSTREAM_HAS_METHOD (lisp_string, marker);
1674 LSTREAM_HAS_METHOD (fixed_buffer, reader);
1675 LSTREAM_HAS_METHOD (fixed_buffer, writer);
1676 LSTREAM_HAS_METHOD (fixed_buffer, rewinder);
1678 LSTREAM_HAS_METHOD (resizing_buffer, writer);
1679 LSTREAM_HAS_METHOD (resizing_buffer, rewinder);
1680 LSTREAM_HAS_METHOD (resizing_buffer, closer);
1682 LSTREAM_HAS_METHOD (dynarr, writer);
1683 LSTREAM_HAS_METHOD (dynarr, rewinder);
1684 LSTREAM_HAS_METHOD (dynarr, closer);
1686 LSTREAM_HAS_METHOD (lisp_buffer, reader);
1687 LSTREAM_HAS_METHOD (lisp_buffer, writer);
1688 LSTREAM_HAS_METHOD (lisp_buffer, rewinder);
1689 LSTREAM_HAS_METHOD (lisp_buffer, marker);
1693 reinit_vars_of_lstream (void)
1697 for (i = 0; i < countof (Vlstream_free_list); i++)
1699 Vlstream_free_list[i] = Qnil;
1700 staticpro_nodump (&Vlstream_free_list[i]);
1705 vars_of_lstream (void)
1707 INIT_LRECORD_IMPLEMENTATION (lstream);
1709 reinit_vars_of_lstream ();