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 and returns it as an unsigned
78 char cast to an int, or EOF on end of file or error.
79 This is a macro and so it is very efficient. The STREAM
80 argument is evaluated more than once.
82 void Lstream_ungetc (Lstream *stream, int c)
83 Push one byte back onto the input queue, cast to unsigned char.
84 This will be the next byte read from the stream. Any number
85 of bytes can be pushed back and will be read in the reverse
86 order they were pushed back -- most recent first. (This is
87 necessary for consistency -- if there are a number of bytes
88 that have been unread and I read and unread a byte, it needs
89 to be the first to be read again.) This is a macro and so it
90 is very efficient. The C argument is only evaluated once but
91 the 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 size_t size = num + lstr->out_buffer_ind;
397 if (size <= lstr->out_buffer_size)
400 /* Maybe chop it down so that we don't buffer more characters
401 than our advertised buffering size. */
402 if ((size > lstr->buffering_size) && !force)
404 size = lstr->buffering_size;
405 /* There might be more data buffered than the buffering size. */
406 if (size <= lstr->out_buffer_ind)
410 DO_REALLOC (lstr->out_buffer, lstr->out_buffer_size, size, unsigned char);
412 return size - lstr->out_buffer_ind;
415 /* Like Lstream_write(), but does not handle line-buffering correctly. */
418 Lstream_write_1 (Lstream *lstr, const void *data, size_t size)
420 const unsigned char *p = (const unsigned char *) data;
422 if (! (lstr->flags & LSTREAM_FL_IS_OPEN))
423 Lstream_internal_error ("lstream not open", lstr);
424 if (! (lstr->flags & LSTREAM_FL_WRITE))
425 Lstream_internal_error ("lstream not open for writing", lstr);
427 int couldnt_write_last_time = 0;
431 /* Figure out how much we can add to the buffer */
432 size_t chunk = Lstream_adding (lstr, size, 0);
435 if (couldnt_write_last_time)
436 /* Ung, we ran out of space and tried to flush
437 the buffer, but it didn't work because the stream
438 writer is refusing to accept any data. So we
439 just have to squirrel away all the rest of the
441 chunk = Lstream_adding (lstr, size, 1);
443 couldnt_write_last_time = 1;
448 memcpy (lstr->out_buffer + lstr->out_buffer_ind, p + off, chunk);
449 lstr->out_buffer_ind += chunk;
450 lstr->byte_count += chunk;
454 /* If the buffer is full and we have more to add, flush it out. */
457 if (Lstream_flush_out (lstr) < 0)
472 /* If the stream is not line-buffered, then we can just call
473 Lstream_write_1(), which writes in chunks. Otherwise, we
474 repeatedly call Lstream_putc(), which knows how to handle
475 line buffering. Returns number of bytes written. */
478 Lstream_write (Lstream *lstr, const void *data, size_t size)
481 const unsigned char *p = (const unsigned char *) data;
485 if (lstr->buffering != LSTREAM_LINE_BUFFERED)
486 return Lstream_write_1 (lstr, data, size);
487 for (i = 0; i < size; i++)
489 if (Lstream_putc (lstr, p[i]) < 0)
492 return i == 0 ? -1 : (ssize_t) i;
496 Lstream_was_blocked_p (Lstream *lstr)
498 return lstr->imp->was_blocked_p ? lstr->imp->was_blocked_p (lstr) : 0;
502 Lstream_raw_read (Lstream *lstr, unsigned char *buffer, size_t size)
504 if (! (lstr->flags & LSTREAM_FL_IS_OPEN))
505 Lstream_internal_error ("lstream not open", lstr);
506 if (! (lstr->flags & LSTREAM_FL_READ))
507 Lstream_internal_error ("lstream not open for reading", lstr);
508 if (!lstr->imp->reader)
509 Lstream_internal_error ("lstream has no reader", lstr);
511 return (lstr->imp->reader) (lstr, buffer, size);
514 /* Assuming the buffer is empty, fill it up again. */
517 Lstream_read_more (Lstream *lstr)
520 ssize_t size_needed = max (1, min (MAX_READ_SIZE, lstr->buffering_size));
522 /* If someone requested a larger buffer size, so be it! */
523 ssize_t size_needed = max (1, lstr->buffering_size);
527 DO_REALLOC (lstr->in_buffer, lstr->in_buffer_size,
528 size_needed, unsigned char);
529 size_gotten = Lstream_raw_read (lstr, lstr->in_buffer, size_needed);
530 lstr->in_buffer_current = max (0, size_gotten);
531 lstr->in_buffer_ind = 0;
532 return size_gotten < 0 ? -1 : size_gotten;
536 Lstream_read (Lstream *lstr, void *data, size_t size)
538 unsigned char *p = (unsigned char *) data;
541 int error_occurred = 0;
546 /* First try to get some data from the unget buffer */
547 chunk = min (size, lstr->unget_buffer_ind);
550 /* The bytes come back in reverse order. */
551 for (; off < chunk; off++)
552 p[off] = lstr->unget_buffer[--lstr->unget_buffer_ind];
553 lstr->byte_count += chunk;
559 /* Take whatever we can from the in buffer */
560 chunk = min (size, lstr->in_buffer_current - lstr->in_buffer_ind);
563 memcpy (p + off, lstr->in_buffer + lstr->in_buffer_ind, chunk);
564 lstr->in_buffer_ind += chunk;
565 lstr->byte_count += chunk;
570 /* If we need some more, try to get some more from the stream's end */
573 ssize_t retval = Lstream_read_more (lstr);
581 /* #### Beware of OFF ending up 0. */
582 if ((lstr->flags & LSTREAM_FL_NO_PARTIAL_CHARS) && off > 0)
584 /* It's quite possible for us to get passed an incomplete
585 character at the end. We need to spit back that
586 incomplete character. */
587 const unsigned char *dataend = p + off - 1;
588 /* Optimize the most common case. */
589 if (!BYTE_ASCII_P (*dataend))
591 /* Go back to the beginning of the last (and possibly partial)
592 character, and bump forward to see if the character is
594 VALIDATE_CHARPTR_BACKWARD (dataend);
595 if (dataend + REP_BYTES_BY_FIRST_BYTE (*dataend) != p + off)
597 size_t newoff = dataend - p;
598 /* If not, chop the size down to ignore the last char
599 and stash it away for next time. */
600 Lstream_unread (lstr, dataend, off - newoff);
606 return off == 0 && error_occurred ? -1 : (ssize_t) off;
610 Lstream_unread (Lstream *lstr, const void *data, size_t size)
612 const unsigned char *p = (const unsigned char *) data;
614 /* 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 lstr->byte_count -= size;
620 /* Bytes have to go on in reverse order -- they are reversed
621 again when read back. */
623 lstr->unget_buffer[lstr->unget_buffer_ind++] = p[size];
627 Lstream_rewind (Lstream *lstr)
629 if (!lstr->imp->rewinder)
630 Lstream_internal_error ("lstream has no rewinder", lstr);
631 if (Lstream_flush (lstr) < 0)
633 lstr->byte_count = 0;
634 return (lstr->imp->rewinder) (lstr);
638 Lstream_seekable_p (Lstream *lstr)
640 if (!lstr->imp->rewinder)
642 if (!lstr->imp->seekable_p)
644 return (lstr->imp->seekable_p) (lstr);
648 Lstream_pseudo_close (Lstream *lstr)
650 if (!lstr->flags & LSTREAM_FL_IS_OPEN)
651 Lstream_internal_error ("lstream is not open", lstr);
653 /* don't check errors here -- best not to risk file descriptor loss */
654 return Lstream_flush (lstr);
658 Lstream_close (Lstream *lstr)
662 if (lstr->flags & LSTREAM_FL_IS_OPEN)
664 rc = Lstream_pseudo_close (lstr);
666 * We used to return immediately if the closer method reported
667 * failure, leaving the stream open. But this is no good, for
668 * the following reasons.
670 * 1. The finalizer method used in GC makes no provision for
671 * failure, so we must not return without freeing buffer
674 * 2. The closer method may have already freed some memory
675 * used for I/O in this stream. E.g. encoding_closer frees
676 * ENCODING_STREAM_DATA(stream)->runoff. If a writer method
677 * tries to use this buffer later, it will write into memory
678 * that may have been allocated elsewhere. Sometime later
679 * you will see a sign that says "Welcome to Crash City."
681 * 3. The closer can report failure if a flush fails in the
682 * other stream in a MULE encoding/decoding stream pair.
683 * The other stream in the pair is closed, but returning
684 * early leaves the current stream open. If we try to
685 * flush the current stream later, we will crash when the
686 * flusher notices that the other end stream is closed.
688 * So, we no longer abort the close if the closer method
689 * reports some kind of failure. We still report the failure
692 if (lstr->imp->closer)
693 if ((lstr->imp->closer) (lstr) < 0)
697 lstr->flags &= ~LSTREAM_FL_IS_OPEN;
698 lstr->byte_count = 0;
699 /* Note that Lstream_flush() reset all the buffer indices. That way,
700 the next call to Lstream_putc(), Lstream_getc(), or Lstream_ungetc()
701 on a closed stream will call into the function equivalents, which will
704 /* We set the pointers to 0 so that we don't lose when this function
705 is called more than once on the same object */
706 if (lstr->out_buffer)
708 xfree (lstr->out_buffer);
709 lstr->out_buffer = 0;
713 xfree (lstr->in_buffer);
716 if (lstr->unget_buffer)
718 xfree (lstr->unget_buffer);
719 lstr->unget_buffer = 0;
726 Lstream_fputc (Lstream *lstr, int c)
728 unsigned char ch = (unsigned char) c;
729 ssize_t retval = Lstream_write_1 (lstr, &ch, 1);
730 if (retval >= 0 && lstr->buffering == LSTREAM_LINE_BUFFERED && ch == '\n')
731 return Lstream_flush_out (lstr);
732 return retval < 0 ? -1 : 0;
736 Lstream_fgetc (Lstream *lstr)
739 if (Lstream_read (lstr, &ch, 1) <= 0)
745 Lstream_fungetc (Lstream *lstr, int c)
747 unsigned char ch = (unsigned char) c;
748 Lstream_unread (lstr, &ch, 1);
752 /************************ some stream implementations *********************/
754 /*********** a stdio stream ***********/
762 #define STDIO_STREAM_DATA(stream) LSTREAM_TYPE_DATA (stream, stdio)
764 DEFINE_LSTREAM_IMPLEMENTATION ("stdio", lstream_stdio,
765 sizeof (struct stdio_stream));
768 make_stdio_stream_1 (FILE *stream, int flags, const char *mode)
771 Lstream *lstr = Lstream_new (lstream_stdio, mode);
772 struct stdio_stream *str = STDIO_STREAM_DATA (lstr);
774 str->closing = flags & LSTR_CLOSING;
775 lstr->flags |= LSTREAM_FL_CLOSE_AT_DISKSAVE;
776 XSETLSTREAM (obj, lstr);
781 make_stdio_input_stream (FILE *stream, int flags)
783 return make_stdio_stream_1 (stream, flags, "r");
787 make_stdio_output_stream (FILE *stream, int flags)
789 return make_stdio_stream_1 (stream, flags, "w");
792 /* #### From reading the Unix 98 specification, it appears that if we
793 want stdio_reader() to be completely correct, we should check for
794 0 < val < size and if so, check to see if an error has occurred.
795 If an error has occurred, but val is non-zero, we should go ahead
796 and act as if the read was successful, but remember in some fashion
797 or other, that an error has occurred, and report that on the next
798 call to stdio_reader instead of calling fread() again.
800 Currently, in such a case, we end up calling fread() twice and we
803 1) this is not harmful, and
804 2) the error will still be reported on the second read.
806 This is probably reasonable, so I don't think we should change this
807 code (it could even be argued that the error might have fixed
808 itself, so we should do the fread() again. */
811 stdio_reader (Lstream *stream, unsigned char *data, size_t size)
813 struct stdio_stream *str = STDIO_STREAM_DATA (stream);
814 size_t val = fread (data, 1, size, str->file);
815 if (!val && ferror (str->file))
821 stdio_writer (Lstream *stream, const unsigned char *data, size_t size)
823 struct stdio_stream *str = STDIO_STREAM_DATA (stream);
824 size_t val = fwrite (data, 1, size, str->file);
825 if (!val && ferror (str->file))
831 stdio_rewinder (Lstream *stream)
833 rewind (STDIO_STREAM_DATA (stream)->file);
838 stdio_seekable_p (Lstream *stream)
841 struct stdio_stream *str = STDIO_STREAM_DATA (stream);
843 if (fstat (fileno (str->file), &lestat) < 0)
845 return S_ISREG (lestat.st_mode);
849 stdio_flusher (Lstream *stream)
851 struct stdio_stream *str = STDIO_STREAM_DATA (stream);
852 if (stream->flags & LSTREAM_FL_WRITE)
853 return fflush (str->file);
859 stdio_closer (Lstream *stream)
861 struct stdio_stream *str = STDIO_STREAM_DATA (stream);
863 return fclose (str->file);
865 if (stream->flags & LSTREAM_FL_WRITE)
866 return fflush (str->file);
871 /*********** a file descriptor ***********/
873 struct filedesc_stream
881 int chars_sans_newline;
882 unsigned int closing :1;
883 unsigned int allow_quit :1;
884 unsigned int blocked_ok :1;
885 unsigned int pty_flushing :1;
886 unsigned int blocking_error_p :1;
889 #define FILEDESC_STREAM_DATA(stream) LSTREAM_TYPE_DATA (stream, filedesc)
891 DEFINE_LSTREAM_IMPLEMENTATION ("filedesc", lstream_filedesc,
892 sizeof (struct filedesc_stream));
894 /* Make a stream that reads from or writes to a file descriptor FILEDESC.
895 OFFSET is the offset from the *current* file pointer that the reading
896 should start at. COUNT is the number of bytes to be read (it is
897 ignored when writing); -1 for unlimited. */
899 make_filedesc_stream_1 (int filedesc, int offset, int count, int flags,
903 Lstream *lstr = Lstream_new (lstream_filedesc, mode);
904 struct filedesc_stream *fstr = FILEDESC_STREAM_DATA (lstr);
906 fstr->closing = !!(flags & LSTR_CLOSING);
907 fstr->allow_quit = !!(flags & LSTR_ALLOW_QUIT);
908 fstr->blocked_ok = !!(flags & LSTR_BLOCKED_OK);
909 fstr->pty_flushing = !!(flags & LSTR_PTY_FLUSHING);
910 fstr->blocking_error_p = 0;
911 fstr->chars_sans_newline = 0;
912 fstr->starting_pos = lseek (filedesc, offset, SEEK_CUR);
913 fstr->current_pos = max (fstr->starting_pos, 0);
917 fstr->end_pos = fstr->starting_pos + count;
918 lstr->flags |= LSTREAM_FL_CLOSE_AT_DISKSAVE;
919 XSETLSTREAM (obj, lstr);
924 make_filedesc_input_stream (int filedesc, int offset, int count, int flags)
926 return make_filedesc_stream_1 (filedesc, offset, count, flags, "r");
930 make_filedesc_output_stream (int filedesc, int offset, int count, int flags)
932 return make_filedesc_stream_1 (filedesc, offset, count, flags, "w");
936 filedesc_reader (Lstream *stream, unsigned char *data, size_t size)
939 struct filedesc_stream *str = FILEDESC_STREAM_DATA (stream);
940 if (str->end_pos >= 0)
941 size = min (size, (size_t) (str->end_pos - str->current_pos));
942 nread = str->allow_quit ?
943 read_allowing_quit (str->fd, data, size) :
944 read (str->fd, data, size);
946 str->current_pos += nread;
951 errno_would_block_p (int val)
954 if (val == EWOULDBLOCK)
965 filedesc_writer (Lstream *stream, const unsigned char *data, size_t size)
967 struct filedesc_stream *str = FILEDESC_STREAM_DATA (stream);
969 int need_newline = 0;
971 /* This function would be simple if it were not for the blasted
972 PTY max-bytes stuff. Why the hell can't they just have written
973 the PTY drivers right so this problem doesn't exist?
975 Maybe all the PTY crap here should be moved into another stream
976 that does nothing but periodically insert EOF's as necessary. */
977 if (str->pty_flushing)
979 /* To make life easy, only send out one line at the most. */
980 const unsigned char *ptr;
982 ptr = (const unsigned char *) memchr (data, '\n', size);
987 if (ptr - data >= str->pty_max_bytes - str->chars_sans_newline)
989 ptr = data + str->pty_max_bytes - str->chars_sans_newline;
995 /**** start of non-PTY-crap ****/
997 retval = str->allow_quit ?
998 write_allowing_quit (str->fd, data, size) :
999 write (str->fd, data, size);
1002 if (retval < 0 && errno_would_block_p (errno) && str->blocked_ok)
1004 str->blocking_error_p = 1;
1007 str->blocking_error_p = 0;
1010 /**** end non-PTY-crap ****/
1012 if (str->pty_flushing)
1014 str->chars_sans_newline += retval;
1015 /* Note that a newline was not among the bytes written out.
1016 Add to the number of non-newline bytes written out,
1017 and flush with an EOF if necessary. Be careful to
1018 keep track of write errors as we go along and look
1019 out for EWOULDBLOCK. */
1020 if (str->chars_sans_newline >= str->pty_max_bytes)
1022 ssize_t retval2 = str->allow_quit ?
1023 write_allowing_quit (str->fd, &str->eof_char, 1) :
1024 write (str->fd, &str->eof_char, 1);
1027 str->chars_sans_newline = 0;
1028 else if (retval2 < 0)
1030 /* Error writing the EOF char. If nothing got written,
1031 then treat this as an error -- either return an error
1032 condition or set the blocking-error flag. */
1035 if (errno_would_block_p (errno) && str->blocked_ok)
1037 str->blocking_error_p = 1;
1049 /* The need_newline flag is necessary because otherwise when the
1050 first byte is a newline, we'd get stuck never writing anything
1051 in pty-flushing mode. */
1055 ssize_t retval2 = str->allow_quit ?
1056 write_allowing_quit (str->fd, &nl, 1) :
1057 write (str->fd, &nl, 1);
1061 str->chars_sans_newline = 0;
1064 else if (retval2 < 0)
1066 /* Error writing the newline char. If nothing got written,
1067 then treat this as an error -- either return an error
1068 condition or set the blocking-error flag. */
1071 if (errno_would_block_p (errno) && str->blocked_ok)
1073 str->blocking_error_p = 1;
1088 filedesc_rewinder (Lstream *stream)
1090 struct filedesc_stream *str = FILEDESC_STREAM_DATA (stream);
1091 if (str->starting_pos < 0 ||
1092 lseek (FILEDESC_STREAM_DATA (stream)->fd, str->starting_pos,
1097 str->current_pos = str->starting_pos;
1103 filedesc_seekable_p (Lstream *stream)
1105 struct filedesc_stream *str = FILEDESC_STREAM_DATA (stream);
1106 if (str->starting_pos < 0)
1112 if (fstat (str->fd, &lestat) < 0)
1114 return S_ISREG (lestat.st_mode);
1119 filedesc_closer (Lstream *stream)
1121 struct filedesc_stream *str = FILEDESC_STREAM_DATA (stream);
1123 return close (str->fd);
1129 filedesc_was_blocked_p (Lstream *stream)
1131 struct filedesc_stream *str = FILEDESC_STREAM_DATA (stream);
1132 return str->blocking_error_p;
1136 filedesc_stream_set_pty_flushing (Lstream *stream, int pty_max_bytes,
1139 struct filedesc_stream *str = FILEDESC_STREAM_DATA (stream);
1140 str->pty_max_bytes = pty_max_bytes;
1141 str->eof_char = eof_char;
1142 str->pty_flushing = 1;
1146 filedesc_stream_fd (Lstream *stream)
1148 struct filedesc_stream *str = FILEDESC_STREAM_DATA (stream);
1152 /*********** read from a Lisp string ***********/
1154 #define LISP_STRING_STREAM_DATA(stream) LSTREAM_TYPE_DATA (stream, lisp_string)
1156 struct lisp_string_stream
1159 Bytecount init_offset;
1160 Bytecount offset, end;
1163 DEFINE_LSTREAM_IMPLEMENTATION ("lisp-string", lstream_lisp_string,
1164 sizeof (struct lisp_string_stream));
1167 make_lisp_string_input_stream (Lisp_Object string, Bytecount offset,
1172 struct lisp_string_stream *str;
1174 CHECK_STRING (string);
1176 len = XSTRING_LENGTH (string) - offset;
1177 assert (offset >= 0);
1179 assert (offset + len <= XSTRING_LENGTH (string));
1181 lstr = Lstream_new (lstream_lisp_string, "r");
1182 str = LISP_STRING_STREAM_DATA (lstr);
1183 str->offset = offset;
1184 str->end = offset + len;
1185 str->init_offset = offset;
1187 XSETLSTREAM (obj, lstr);
1192 lisp_string_reader (Lstream *stream, unsigned char *data, size_t size)
1194 struct lisp_string_stream *str = LISP_STRING_STREAM_DATA (stream);
1195 /* Don't lose if the string shrank past us ... */
1196 Bytecount offset = min (str->offset, XSTRING_LENGTH (str->obj));
1197 Bufbyte *strstart = XSTRING_DATA (str->obj);
1198 Bufbyte *start = strstart + offset;
1200 /* ... or if someone changed the string and we ended up in the
1201 middle of a character. */
1202 /* Being in the middle of a character is `normal' unless
1203 LSTREAM_NO_PARTIAL_CHARS - mrb */
1204 if (stream->flags & LSTREAM_FL_NO_PARTIAL_CHARS)
1205 VALIDATE_CHARPTR_BACKWARD (start);
1206 offset = start - strstart;
1207 size = min (size, (size_t) (str->end - offset));
1208 memcpy (data, start, size);
1209 str->offset = offset + size;
1214 lisp_string_rewinder (Lstream *stream)
1216 struct lisp_string_stream *str = LISP_STRING_STREAM_DATA (stream);
1217 int pos = str->init_offset;
1220 /* Don't lose if the string shrank past us ... */
1221 pos = min (pos, XSTRING_LENGTH (str->obj));
1222 /* ... or if someone changed the string and we ended up in the
1223 middle of a character. */
1225 Bufbyte *strstart = XSTRING_DATA (str->obj);
1226 Bufbyte *start = strstart + pos;
1227 VALIDATE_CHARPTR_BACKWARD (start);
1228 pos = start - strstart;
1235 lisp_string_marker (Lisp_Object stream)
1237 struct lisp_string_stream *str = LISP_STRING_STREAM_DATA (XLSTREAM (stream));
1241 /*********** a fixed buffer ***********/
1243 #define FIXED_BUFFER_STREAM_DATA(stream) \
1244 LSTREAM_TYPE_DATA (stream, fixed_buffer)
1246 struct fixed_buffer_stream
1248 const unsigned char *inbuf;
1249 unsigned char *outbuf;
1254 DEFINE_LSTREAM_IMPLEMENTATION ("fixed-buffer", lstream_fixed_buffer,
1255 sizeof (struct fixed_buffer_stream));
1258 make_fixed_buffer_input_stream (const void *buf, size_t size)
1261 Lstream *lstr = Lstream_new (lstream_fixed_buffer, "r");
1262 struct fixed_buffer_stream *str = FIXED_BUFFER_STREAM_DATA (lstr);
1263 str->inbuf = (const unsigned char *) buf;
1265 XSETLSTREAM (obj, lstr);
1270 make_fixed_buffer_output_stream (void *buf, size_t size)
1273 Lstream *lstr = Lstream_new (lstream_fixed_buffer, "w");
1274 struct fixed_buffer_stream *str = FIXED_BUFFER_STREAM_DATA (lstr);
1275 str->outbuf = (unsigned char *) buf;
1277 XSETLSTREAM (obj, lstr);
1282 fixed_buffer_reader (Lstream *stream, unsigned char *data, size_t size)
1284 struct fixed_buffer_stream *str = FIXED_BUFFER_STREAM_DATA (stream);
1285 size = min (size, str->size - str->offset);
1286 memcpy (data, str->inbuf + str->offset, size);
1287 str->offset += size;
1292 fixed_buffer_writer (Lstream *stream, const unsigned char *data, size_t size)
1294 struct fixed_buffer_stream *str = FIXED_BUFFER_STREAM_DATA (stream);
1295 if (str->offset == str->size)
1297 /* If we're at the end, just throw away the data and pretend
1298 we wrote all of it. If we return 0, then the lstream routines
1299 will try again and again to write it out. */
1302 size = min (size, str->size - str->offset);
1303 memcpy (str->outbuf + str->offset, data, size);
1304 str->offset += size;
1309 fixed_buffer_rewinder (Lstream *stream)
1311 FIXED_BUFFER_STREAM_DATA (stream)->offset = 0;
1315 const unsigned char *
1316 fixed_buffer_input_stream_ptr (Lstream *stream)
1318 assert (stream->imp == lstream_fixed_buffer);
1319 return FIXED_BUFFER_STREAM_DATA (stream)->inbuf;
1323 fixed_buffer_output_stream_ptr (Lstream *stream)
1325 assert (stream->imp == lstream_fixed_buffer);
1326 return FIXED_BUFFER_STREAM_DATA (stream)->outbuf;
1329 /*********** write to a resizing buffer ***********/
1331 #define RESIZING_BUFFER_STREAM_DATA(stream) \
1332 LSTREAM_TYPE_DATA (stream, resizing_buffer)
1334 struct resizing_buffer_stream
1342 DEFINE_LSTREAM_IMPLEMENTATION ("resizing-buffer", lstream_resizing_buffer,
1343 sizeof (struct resizing_buffer_stream));
1346 make_resizing_buffer_output_stream (void)
1349 XSETLSTREAM (obj, Lstream_new (lstream_resizing_buffer, "w"));
1354 resizing_buffer_writer (Lstream *stream, const unsigned char *data, size_t size)
1356 struct resizing_buffer_stream *str = RESIZING_BUFFER_STREAM_DATA (stream);
1357 DO_REALLOC (str->buf, str->allocked, str->stored + size, unsigned char);
1358 memcpy (str->buf + str->stored, data, size);
1359 str->stored += size;
1360 str->max_stored = max (str->max_stored, str->stored);
1365 resizing_buffer_rewinder (Lstream *stream)
1367 RESIZING_BUFFER_STREAM_DATA (stream)->stored = 0;
1372 resizing_buffer_closer (Lstream *stream)
1374 struct resizing_buffer_stream *str = RESIZING_BUFFER_STREAM_DATA (stream);
1384 resizing_buffer_stream_ptr (Lstream *stream)
1386 return RESIZING_BUFFER_STREAM_DATA (stream)->buf;
1389 /*********** write to an unsigned-char dynarr ***********/
1391 /* Note: If you have a dynarr whose type is not unsigned_char_dynarr
1392 but which is really just an unsigned_char_dynarr (e.g. its type
1393 is Bufbyte or Extbyte), just cast to unsigned_char_dynarr. */
1395 #define DYNARR_STREAM_DATA(stream) \
1396 LSTREAM_TYPE_DATA (stream, dynarr)
1398 struct dynarr_stream
1400 unsigned_char_dynarr *dyn;
1403 DEFINE_LSTREAM_IMPLEMENTATION ("dynarr", lstream_dynarr,
1404 sizeof (struct dynarr_stream));
1407 make_dynarr_output_stream (unsigned_char_dynarr *dyn)
1410 XSETLSTREAM (obj, Lstream_new (lstream_dynarr, "w"));
1411 DYNARR_STREAM_DATA (XLSTREAM (obj))->dyn = dyn;
1416 dynarr_writer (Lstream *stream, const unsigned char *data, size_t size)
1418 struct dynarr_stream *str = DYNARR_STREAM_DATA (stream);
1419 Dynarr_add_many (str->dyn, data, size);
1424 dynarr_rewinder (Lstream *stream)
1426 Dynarr_reset (DYNARR_STREAM_DATA (stream)->dyn);
1431 dynarr_closer (Lstream *stream)
1436 /************ read from or write to a Lisp buffer ************/
1438 /* Note: Lisp-buffer read streams never return partial characters,
1439 and Lisp-buffer write streams expect to never get partial
1442 #define LISP_BUFFER_STREAM_DATA(stream) \
1443 LSTREAM_TYPE_DATA (stream, lisp_buffer)
1445 struct lisp_buffer_stream
1448 Lisp_Object orig_start;
1449 /* we use markers to properly deal with insertion/deletion */
1450 Lisp_Object start, end;
1454 DEFINE_LSTREAM_IMPLEMENTATION ("lisp-buffer", lstream_lisp_buffer,
1455 sizeof (struct lisp_buffer_stream));
1458 make_lisp_buffer_stream_1 (struct buffer *buf, Bufpos start, Bufpos end,
1459 int flags, const char *mode)
1463 struct lisp_buffer_stream *str;
1465 int reading = !strcmp (mode, "r");
1467 /* Make sure the luser didn't pass "w" in. */
1468 if (!strcmp (mode, "w"))
1471 if (flags & LSTR_IGNORE_ACCESSIBLE)
1473 bmin = BUF_BEG (buf);
1478 bmin = BUF_BEGV (buf);
1479 bmax = BUF_ZV (buf);
1486 assert (bmin <= start);
1487 assert (start <= bmax);
1490 assert (bmin <= end);
1491 assert (end <= bmax);
1492 assert (start <= end);
1495 lstr = Lstream_new (lstream_lisp_buffer, mode);
1496 str = LISP_BUFFER_STREAM_DATA (lstr);
1501 XSETBUFFER (buffer, buf);
1502 marker = Fmake_marker ();
1503 Fset_marker (marker, make_int (start), buffer);
1504 str->start = marker;
1505 marker = Fmake_marker ();
1506 Fset_marker (marker, make_int (start), buffer);
1507 str->orig_start = marker;
1510 marker = Fmake_marker ();
1511 Fset_marker (marker, make_int (end), buffer);
1516 str->buffer = buffer;
1519 XSETLSTREAM (obj, lstr);
1524 make_lisp_buffer_input_stream (struct buffer *buf, Bufpos start, Bufpos end,
1527 return make_lisp_buffer_stream_1 (buf, start, end, flags, "r");
1531 make_lisp_buffer_output_stream (struct buffer *buf, Bufpos pos, int flags)
1533 Lisp_Object lstr = make_lisp_buffer_stream_1 (buf, pos, 0, flags, "wc");
1535 Lstream_set_character_mode (XLSTREAM (lstr));
1540 lisp_buffer_reader (Lstream *stream, unsigned char *data, size_t size)
1542 struct lisp_buffer_stream *str = LISP_BUFFER_STREAM_DATA (stream);
1543 unsigned char *orig_data = data;
1546 struct buffer *buf = XBUFFER (str->buffer);
1548 if (!BUFFER_LIVE_P (buf))
1549 return 0; /* Fut. */
1551 /* NOTE: We do all our operations in Bytind's.
1552 Keep in mind that SIZE is a value in bytes, not chars. */
1554 start = bi_marker_position (str->start);
1555 end = bi_marker_position (str->end);
1556 if (!(str->flags & LSTR_IGNORE_ACCESSIBLE))
1558 start = bytind_clip_to_bounds (BI_BUF_BEGV (buf), start,
1560 end = bytind_clip_to_bounds (BI_BUF_BEGV (buf), end,
1564 size = min (size, (size_t) (end - start));
1566 /* We cannot return a partial character. */
1567 VALIDATE_BYTIND_BACKWARD (buf, end);
1574 if (str->flags & LSTR_IGNORE_ACCESSIBLE)
1575 ceil = BI_BUF_CEILING_OF_IGNORE_ACCESSIBLE (buf, start);
1577 ceil = BI_BUF_CEILING_OF (buf, start);
1578 chunk = min (ceil, end) - start;
1579 memcpy (data, BI_BUF_BYTE_ADDRESS (buf, start), chunk);
1584 if (EQ (buf->selective_display, Qt) && str->flags & LSTR_SELECTIVE)
1586 /* What a kludge. What a kludge. What a kludge. */
1588 for (p = orig_data; p < data; p++)
1593 set_bi_marker_position (str->start, end);
1594 return data - orig_data;
1598 lisp_buffer_writer (Lstream *stream, const unsigned char *data, size_t size)
1600 struct lisp_buffer_stream *str = LISP_BUFFER_STREAM_DATA (stream);
1602 struct buffer *buf = XBUFFER (str->buffer);
1604 if (!BUFFER_LIVE_P (buf))
1605 return 0; /* Fut. */
1607 pos = marker_position (str->start);
1608 pos += buffer_insert_raw_string_1 (buf, pos, data, size, 0);
1609 set_marker_position (str->start, pos);
1614 lisp_buffer_rewinder (Lstream *stream)
1616 struct lisp_buffer_stream *str =
1617 LISP_BUFFER_STREAM_DATA (stream);
1618 struct buffer *buf = XBUFFER (str->buffer);
1619 long pos = marker_position (str->orig_start);
1620 if (!BUFFER_LIVE_P (buf))
1621 return -1; /* Fut. */
1622 if (pos > BUF_ZV (buf))
1624 if (pos < marker_position (str->orig_start))
1625 pos = marker_position (str->orig_start);
1626 if (MARKERP (str->end) && pos > marker_position (str->end))
1627 pos = marker_position (str->end);
1628 set_marker_position (str->start, pos);
1633 lisp_buffer_marker (Lisp_Object stream)
1635 struct lisp_buffer_stream *str =
1636 LISP_BUFFER_STREAM_DATA (XLSTREAM (stream));
1638 mark_object (str->start);
1639 mark_object (str->end);
1644 lisp_buffer_stream_startpos (Lstream *stream)
1646 return marker_position (LISP_BUFFER_STREAM_DATA (stream)->start);
1650 /************************************************************************/
1651 /* initialization */
1652 /************************************************************************/
1655 lstream_type_create (void)
1657 LSTREAM_HAS_METHOD (stdio, reader);
1658 LSTREAM_HAS_METHOD (stdio, writer);
1659 LSTREAM_HAS_METHOD (stdio, rewinder);
1660 LSTREAM_HAS_METHOD (stdio, seekable_p);
1661 LSTREAM_HAS_METHOD (stdio, flusher);
1662 LSTREAM_HAS_METHOD (stdio, closer);
1664 LSTREAM_HAS_METHOD (filedesc, reader);
1665 LSTREAM_HAS_METHOD (filedesc, writer);
1666 LSTREAM_HAS_METHOD (filedesc, was_blocked_p);
1667 LSTREAM_HAS_METHOD (filedesc, rewinder);
1668 LSTREAM_HAS_METHOD (filedesc, seekable_p);
1669 LSTREAM_HAS_METHOD (filedesc, closer);
1671 LSTREAM_HAS_METHOD (lisp_string, reader);
1672 LSTREAM_HAS_METHOD (lisp_string, rewinder);
1673 LSTREAM_HAS_METHOD (lisp_string, marker);
1675 LSTREAM_HAS_METHOD (fixed_buffer, reader);
1676 LSTREAM_HAS_METHOD (fixed_buffer, writer);
1677 LSTREAM_HAS_METHOD (fixed_buffer, rewinder);
1679 LSTREAM_HAS_METHOD (resizing_buffer, writer);
1680 LSTREAM_HAS_METHOD (resizing_buffer, rewinder);
1681 LSTREAM_HAS_METHOD (resizing_buffer, closer);
1683 LSTREAM_HAS_METHOD (dynarr, writer);
1684 LSTREAM_HAS_METHOD (dynarr, rewinder);
1685 LSTREAM_HAS_METHOD (dynarr, closer);
1687 LSTREAM_HAS_METHOD (lisp_buffer, reader);
1688 LSTREAM_HAS_METHOD (lisp_buffer, writer);
1689 LSTREAM_HAS_METHOD (lisp_buffer, rewinder);
1690 LSTREAM_HAS_METHOD (lisp_buffer, marker);
1694 reinit_vars_of_lstream (void)
1698 for (i = 0; i < countof (Vlstream_free_list); i++)
1700 Vlstream_free_list[i] = Qnil;
1701 staticpro_nodump (&Vlstream_free_list[i]);
1706 vars_of_lstream (void)
1708 INIT_LRECORD_IMPLEMENTATION (lstream);
1710 reinit_vars_of_lstream ();