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 aligned_sizeof_lstream (size_t lstream_type_specific_size)
185 return ALIGN_SIZE (offsetof (Lstream, data) + lstream_type_specific_size,
186 ALIGNOF (max_align_t));
190 sizeof_lstream (const void *header)
192 return aligned_sizeof_lstream (((const Lstream *) header)->imp->size);
195 DEFINE_LRECORD_SEQUENCE_IMPLEMENTATION ("stream", lstream,
196 mark_lstream, print_lstream,
197 finalize_lstream, 0, 0, 0,
198 sizeof_lstream, Lstream);
201 Lstream_set_buffering (Lstream *lstr, Lstream_buffering buffering,
204 lstr->buffering = buffering;
207 case LSTREAM_UNBUFFERED:
208 lstr->buffering_size = 0; break;
209 case LSTREAM_BLOCK_BUFFERED:
210 lstr->buffering_size = DEFAULT_BLOCK_BUFFERING_SIZE; break;
211 case LSTREAM_BLOCKN_BUFFERED:
212 lstr->buffering_size = buffering_size; break;
213 case LSTREAM_LINE_BUFFERED:
214 case LSTREAM_UNLIMITED:
215 lstr->buffering_size = INT_MAX; break;
219 static const Lstream_implementation *lstream_types[32];
220 static Lisp_Object Vlstream_free_list[32];
221 static int lstream_type_count;
224 Lstream_new (const Lstream_implementation *imp, const char *mode)
229 for (i = 0; i < lstream_type_count; i++)
231 if (lstream_types[i] == imp)
235 if (i == lstream_type_count)
237 assert (lstream_type_count < countof (lstream_types));
238 lstream_types[lstream_type_count] = imp;
239 Vlstream_free_list[lstream_type_count] =
240 make_lcrecord_list (aligned_sizeof_lstream (imp->size),
242 lstream_type_count++;
245 p = XLSTREAM (allocate_managed_lcrecord (Vlstream_free_list[i]));
246 /* Zero it out, except the header. */
247 memset ((char *) p + sizeof (p->header), '\0',
248 aligned_sizeof_lstream (imp->size) - sizeof (p->header));
250 Lstream_set_buffering (p, LSTREAM_BLOCK_BUFFERED, 0);
251 p->flags = LSTREAM_FL_IS_OPEN;
253 /* convert mode (one of "r", "w", "rc", "wc") to p->flags */
254 assert (mode[0] == 'r' || mode[0] == 'w');
255 assert (mode[1] == 'c' || mode[1] == '\0');
256 p->flags |= (mode[0] == 'r' ? LSTREAM_FL_READ : LSTREAM_FL_WRITE);
258 p->flags |= LSTREAM_FL_NO_PARTIAL_CHARS;
264 Lstream_set_character_mode (Lstream *lstr)
266 lstr->flags |= LSTREAM_FL_NO_PARTIAL_CHARS;
270 Lstream_delete (Lstream *lstr)
275 XSETLSTREAM (val, lstr);
276 for (i = 0; i < lstream_type_count; i++)
278 if (lstream_types[i] == lstr->imp)
280 free_managed_lcrecord (Vlstream_free_list[i], val);
288 #define Lstream_internal_error(reason, lstr) \
289 Lstream_signal_simple_error ("Internal error: " reason, lstr)
291 static void Lstream_signal_simple_error (const char *reason, Lstream *lstr)
294 XSETLSTREAM (obj, lstr);
295 signal_simple_error (reason, obj);
299 Lstream_reopen (Lstream *lstr)
301 if (lstr->flags & LSTREAM_FL_IS_OPEN)
302 Lstream_internal_error ("lstream already open", lstr);
303 lstr->flags |= LSTREAM_FL_IS_OPEN;
306 /* Attempt to flush out all of the buffered data for writing. */
309 Lstream_flush_out (Lstream *lstr)
313 while (lstr->out_buffer_ind > 0)
315 size_t size = lstr->out_buffer_ind;
316 if (! (lstr->flags & LSTREAM_FL_IS_OPEN))
317 Lstream_internal_error ("lstream not open", lstr);
318 if (! (lstr->flags & LSTREAM_FL_WRITE))
319 Lstream_internal_error ("lstream not open for writing", lstr);
320 if (!lstr->imp->writer)
321 Lstream_internal_error ("lstream has no writer", lstr);
323 if (lstr->flags & LSTREAM_FL_NO_PARTIAL_CHARS)
324 /* It's quite possible for us to get passed an incomplete
325 character at the end. We need to spit back that
326 incomplete character. */
328 const unsigned char *data = lstr->out_buffer;
329 const unsigned char *dataend = data + size - 1;
330 assert (size > 0); /* safety check ... */
331 /* Optimize the most common case. */
332 if (!BYTE_ASCII_P (*dataend))
334 /* Go back to the beginning of the last (and possibly partial)
335 character, and bump forward to see if the character is
337 VALIDATE_CHARPTR_BACKWARD (dataend);
338 if (dataend + REP_BYTES_BY_FIRST_BYTE (*dataend) != data + size)
339 /* If not, chop the size down to ignore the last char
340 and stash it away for next time. */
341 size = dataend - data;
342 /* If we don't even have one character to write, then just
349 num_written = (lstr->imp->writer) (lstr, lstr->out_buffer, size);
350 if (num_written == 0)
351 /* If nothing got written, then just hold the data. This may
352 occur, for example, if this stream does non-blocking I/O;
353 the attempt to write the data might have resulted in an
354 EWOULDBLOCK error. */
356 else if (num_written >= lstr->out_buffer_ind)
357 lstr->out_buffer_ind = 0;
358 else if (num_written > 0)
360 memmove (lstr->out_buffer, lstr->out_buffer + num_written,
361 lstr->out_buffer_ind - num_written);
362 lstr->out_buffer_ind -= num_written;
365 /* If error, just hold the data, for similar reasons as above. */
369 if (lstr->imp->flusher)
370 return (lstr->imp->flusher) (lstr);
376 Lstream_flush (Lstream *lstr)
378 if (Lstream_flush_out (lstr) < 0)
381 /* clear out buffered data */
382 lstr->in_buffer_current = lstr->in_buffer_ind = 0;
383 lstr->unget_buffer_ind = 0;
388 /* We want to add NUM characters. This function ensures that the
389 buffer is large enough for this (per the buffering size specified
390 in the stream) and returns the number of characters we can
391 actually write. If FORCE is set, ignore the buffering size
392 and go ahead and make space for all the chars even if it exceeds
393 the buffering size. (This is used to deal with the possibility
394 that the stream writer might refuse to write any bytes now, e.g.
395 if it's getting EWOULDBLOCK errors. We have to keep stocking them
396 up until they can be written, so as to avoid losing data. */
399 Lstream_adding (Lstream *lstr, size_t num, int force)
401 size_t size = num + lstr->out_buffer_ind;
403 if (size <= lstr->out_buffer_size)
406 /* Maybe chop it down so that we don't buffer more characters
407 than our advertised buffering size. */
408 if ((size > lstr->buffering_size) && !force)
410 size = lstr->buffering_size;
411 /* There might be more data buffered than the buffering size. */
412 if (size <= lstr->out_buffer_ind)
416 DO_REALLOC (lstr->out_buffer, lstr->out_buffer_size, size, unsigned char);
418 return size - lstr->out_buffer_ind;
421 /* Like Lstream_write(), but does not handle line-buffering correctly. */
424 Lstream_write_1 (Lstream *lstr, const void *data, size_t size)
426 const unsigned char *p = (const unsigned char *) data;
428 if (! (lstr->flags & LSTREAM_FL_IS_OPEN))
429 Lstream_internal_error ("lstream not open", lstr);
430 if (! (lstr->flags & LSTREAM_FL_WRITE))
431 Lstream_internal_error ("lstream not open for writing", lstr);
433 int couldnt_write_last_time = 0;
437 /* Figure out how much we can add to the buffer */
438 size_t chunk = Lstream_adding (lstr, size, 0);
441 if (couldnt_write_last_time)
442 /* Ung, we ran out of space and tried to flush
443 the buffer, but it didn't work because the stream
444 writer is refusing to accept any data. So we
445 just have to squirrel away all the rest of the
447 chunk = Lstream_adding (lstr, size, 1);
449 couldnt_write_last_time = 1;
454 memcpy (lstr->out_buffer + lstr->out_buffer_ind, p + off, chunk);
455 lstr->out_buffer_ind += chunk;
456 lstr->byte_count += chunk;
460 /* If the buffer is full and we have more to add, flush it out. */
463 if (Lstream_flush_out (lstr) < 0)
478 /* If the stream is not line-buffered, then we can just call
479 Lstream_write_1(), which writes in chunks. Otherwise, we
480 repeatedly call Lstream_putc(), which knows how to handle
481 line buffering. Returns number of bytes written. */
484 Lstream_write (Lstream *lstr, const void *data, size_t size)
487 const unsigned char *p = (const unsigned char *) data;
491 if (lstr->buffering != LSTREAM_LINE_BUFFERED)
492 return Lstream_write_1 (lstr, data, size);
493 for (i = 0; i < size; i++)
495 if (Lstream_putc (lstr, p[i]) < 0)
498 return i == 0 ? -1 : (ssize_t) i;
502 Lstream_was_blocked_p (Lstream *lstr)
504 return lstr->imp->was_blocked_p ? lstr->imp->was_blocked_p (lstr) : 0;
508 Lstream_raw_read (Lstream *lstr, unsigned char *buffer, size_t size)
510 if (! (lstr->flags & LSTREAM_FL_IS_OPEN))
511 Lstream_internal_error ("lstream not open", lstr);
512 if (! (lstr->flags & LSTREAM_FL_READ))
513 Lstream_internal_error ("lstream not open for reading", lstr);
514 if (!lstr->imp->reader)
515 Lstream_internal_error ("lstream has no reader", lstr);
517 return (lstr->imp->reader) (lstr, buffer, size);
520 /* Assuming the buffer is empty, fill it up again. */
523 Lstream_read_more (Lstream *lstr)
526 ssize_t size_needed = max (1, min (MAX_READ_SIZE, lstr->buffering_size));
528 /* If someone requested a larger buffer size, so be it! */
529 ssize_t size_needed = max (1, lstr->buffering_size);
533 DO_REALLOC (lstr->in_buffer, lstr->in_buffer_size,
534 size_needed, unsigned char);
535 size_gotten = Lstream_raw_read (lstr, lstr->in_buffer, size_needed);
536 lstr->in_buffer_current = max (0, size_gotten);
537 lstr->in_buffer_ind = 0;
538 return size_gotten < 0 ? -1 : size_gotten;
542 Lstream_read (Lstream *lstr, void *data, size_t size)
544 unsigned char *p = (unsigned char *) data;
547 int error_occurred = 0;
552 /* First try to get some data from the unget buffer */
553 chunk = min (size, lstr->unget_buffer_ind);
556 /* The bytes come back in reverse order. */
557 for (; off < chunk; off++)
558 p[off] = lstr->unget_buffer[--lstr->unget_buffer_ind];
559 lstr->byte_count += chunk;
565 /* Take whatever we can from the in buffer */
566 chunk = min (size, lstr->in_buffer_current - lstr->in_buffer_ind);
569 memcpy (p + off, lstr->in_buffer + lstr->in_buffer_ind, chunk);
570 lstr->in_buffer_ind += chunk;
571 lstr->byte_count += chunk;
576 /* If we need some more, try to get some more from the stream's end */
579 ssize_t retval = Lstream_read_more (lstr);
587 /* #### Beware of OFF ending up 0. */
588 if ((lstr->flags & LSTREAM_FL_NO_PARTIAL_CHARS) && off > 0)
590 /* It's quite possible for us to get passed an incomplete
591 character at the end. We need to spit back that
592 incomplete character. */
593 const unsigned char *dataend = p + off - 1;
594 /* Optimize the most common case. */
595 if (!BYTE_ASCII_P (*dataend))
597 /* Go back to the beginning of the last (and possibly partial)
598 character, and bump forward to see if the character is
600 VALIDATE_CHARPTR_BACKWARD (dataend);
601 if (dataend + REP_BYTES_BY_FIRST_BYTE (*dataend) != p + off)
603 size_t newoff = dataend - p;
604 /* If not, chop the size down to ignore the last char
605 and stash it away for next time. */
606 Lstream_unread (lstr, dataend, off - newoff);
612 return off == 0 && error_occurred ? -1 : (ssize_t) off;
616 Lstream_unread (Lstream *lstr, const void *data, size_t size)
618 const unsigned char *p = (const unsigned char *) data;
620 /* Make sure buffer is big enough */
621 DO_REALLOC (lstr->unget_buffer, lstr->unget_buffer_size,
622 lstr->unget_buffer_ind + size, unsigned char);
624 lstr->byte_count -= size;
626 /* Bytes have to go on in reverse order -- they are reversed
627 again when read back. */
629 lstr->unget_buffer[lstr->unget_buffer_ind++] = p[size];
633 Lstream_rewind (Lstream *lstr)
635 if (!lstr->imp->rewinder)
636 Lstream_internal_error ("lstream has no rewinder", lstr);
637 if (Lstream_flush (lstr) < 0)
639 lstr->byte_count = 0;
640 return (lstr->imp->rewinder) (lstr);
644 Lstream_seekable_p (Lstream *lstr)
646 if (!lstr->imp->rewinder)
648 if (!lstr->imp->seekable_p)
650 return (lstr->imp->seekable_p) (lstr);
654 Lstream_pseudo_close (Lstream *lstr)
656 if (!lstr->flags & LSTREAM_FL_IS_OPEN)
657 Lstream_internal_error ("lstream is not open", lstr);
659 /* don't check errors here -- best not to risk file descriptor loss */
660 return Lstream_flush (lstr);
664 Lstream_close (Lstream *lstr)
668 if (lstr->flags & LSTREAM_FL_IS_OPEN)
670 rc = Lstream_pseudo_close (lstr);
672 * We used to return immediately if the closer method reported
673 * failure, leaving the stream open. But this is no good, for
674 * the following reasons.
676 * 1. The finalizer method used in GC makes no provision for
677 * failure, so we must not return without freeing buffer
680 * 2. The closer method may have already freed some memory
681 * used for I/O in this stream. E.g. encoding_closer frees
682 * ENCODING_STREAM_DATA(stream)->runoff. If a writer method
683 * tries to use this buffer later, it will write into memory
684 * that may have been allocated elsewhere. Sometime later
685 * you will see a sign that says "Welcome to Crash City."
687 * 3. The closer can report failure if a flush fails in the
688 * other stream in a MULE encoding/decoding stream pair.
689 * The other stream in the pair is closed, but returning
690 * early leaves the current stream open. If we try to
691 * flush the current stream later, we will crash when the
692 * flusher notices that the other end stream is closed.
694 * So, we no longer abort the close if the closer method
695 * reports some kind of failure. We still report the failure
698 if (lstr->imp->closer)
699 if ((lstr->imp->closer) (lstr) < 0)
703 lstr->flags &= ~LSTREAM_FL_IS_OPEN;
704 lstr->byte_count = 0;
705 /* Note that Lstream_flush() reset all the buffer indices. That way,
706 the next call to Lstream_putc(), Lstream_getc(), or Lstream_ungetc()
707 on a closed stream will call into the function equivalents, which will
710 /* We set the pointers to 0 so that we don't lose when this function
711 is called more than once on the same object */
712 if (lstr->out_buffer)
714 xfree (lstr->out_buffer);
715 lstr->out_buffer = 0;
719 xfree (lstr->in_buffer);
722 if (lstr->unget_buffer)
724 xfree (lstr->unget_buffer);
725 lstr->unget_buffer = 0;
732 Lstream_fputc (Lstream *lstr, int c)
734 unsigned char ch = (unsigned char) c;
735 ssize_t retval = Lstream_write_1 (lstr, &ch, 1);
736 if (retval >= 0 && lstr->buffering == LSTREAM_LINE_BUFFERED && ch == '\n')
737 return Lstream_flush_out (lstr);
738 return retval < 0 ? -1 : 0;
742 Lstream_fgetc (Lstream *lstr)
745 if (Lstream_read (lstr, &ch, 1) <= 0)
751 Lstream_fungetc (Lstream *lstr, int c)
753 unsigned char ch = (unsigned char) c;
754 Lstream_unread (lstr, &ch, 1);
758 /************************ some stream implementations *********************/
760 /*********** a stdio stream ***********/
768 #define STDIO_STREAM_DATA(stream) LSTREAM_TYPE_DATA (stream, stdio)
770 DEFINE_LSTREAM_IMPLEMENTATION ("stdio", lstream_stdio,
771 sizeof (struct stdio_stream));
774 make_stdio_stream_1 (FILE *stream, int flags, const char *mode)
777 Lstream *lstr = Lstream_new (lstream_stdio, mode);
778 struct stdio_stream *str = STDIO_STREAM_DATA (lstr);
780 str->closing = flags & LSTR_CLOSING;
781 lstr->flags |= LSTREAM_FL_CLOSE_AT_DISKSAVE;
782 XSETLSTREAM (obj, lstr);
787 make_stdio_input_stream (FILE *stream, int flags)
789 return make_stdio_stream_1 (stream, flags, "r");
793 make_stdio_output_stream (FILE *stream, int flags)
795 return make_stdio_stream_1 (stream, flags, "w");
798 /* #### From reading the Unix 98 specification, it appears that if we
799 want stdio_reader() to be completely correct, we should check for
800 0 < val < size and if so, check to see if an error has occurred.
801 If an error has occurred, but val is non-zero, we should go ahead
802 and act as if the read was successful, but remember in some fashion
803 or other, that an error has occurred, and report that on the next
804 call to stdio_reader instead of calling fread() again.
806 Currently, in such a case, we end up calling fread() twice and we
809 1) this is not harmful, and
810 2) the error will still be reported on the second read.
812 This is probably reasonable, so I don't think we should change this
813 code (it could even be argued that the error might have fixed
814 itself, so we should do the fread() again. */
817 stdio_reader (Lstream *stream, unsigned char *data, size_t size)
819 struct stdio_stream *str = STDIO_STREAM_DATA (stream);
820 size_t val = fread (data, 1, size, str->file);
821 if (!val && ferror (str->file))
827 stdio_writer (Lstream *stream, const unsigned char *data, size_t size)
829 struct stdio_stream *str = STDIO_STREAM_DATA (stream);
830 size_t val = fwrite (data, 1, size, str->file);
831 if (!val && ferror (str->file))
837 stdio_rewinder (Lstream *stream)
839 rewind (STDIO_STREAM_DATA (stream)->file);
844 stdio_seekable_p (Lstream *stream)
847 struct stdio_stream *str = STDIO_STREAM_DATA (stream);
849 if (fstat (fileno (str->file), &lestat) < 0)
851 return S_ISREG (lestat.st_mode);
855 stdio_flusher (Lstream *stream)
857 struct stdio_stream *str = STDIO_STREAM_DATA (stream);
858 if (stream->flags & LSTREAM_FL_WRITE)
859 return fflush (str->file);
865 stdio_closer (Lstream *stream)
867 struct stdio_stream *str = STDIO_STREAM_DATA (stream);
869 return fclose (str->file);
871 if (stream->flags & LSTREAM_FL_WRITE)
872 return fflush (str->file);
877 /*********** a file descriptor ***********/
879 struct filedesc_stream
887 int chars_sans_newline;
888 unsigned int closing :1;
889 unsigned int allow_quit :1;
890 unsigned int blocked_ok :1;
891 unsigned int pty_flushing :1;
892 unsigned int blocking_error_p :1;
895 #define FILEDESC_STREAM_DATA(stream) LSTREAM_TYPE_DATA (stream, filedesc)
897 DEFINE_LSTREAM_IMPLEMENTATION ("filedesc", lstream_filedesc,
898 sizeof (struct filedesc_stream));
900 /* Make a stream that reads from or writes to a file descriptor FILEDESC.
901 OFFSET is the offset from the *current* file pointer that the reading
902 should start at. COUNT is the number of bytes to be read (it is
903 ignored when writing); -1 for unlimited. */
905 make_filedesc_stream_1 (int filedesc, int offset, int count, int flags,
909 Lstream *lstr = Lstream_new (lstream_filedesc, mode);
910 struct filedesc_stream *fstr = FILEDESC_STREAM_DATA (lstr);
912 fstr->closing = !!(flags & LSTR_CLOSING);
913 fstr->allow_quit = !!(flags & LSTR_ALLOW_QUIT);
914 fstr->blocked_ok = !!(flags & LSTR_BLOCKED_OK);
915 fstr->pty_flushing = !!(flags & LSTR_PTY_FLUSHING);
916 fstr->blocking_error_p = 0;
917 fstr->chars_sans_newline = 0;
918 fstr->starting_pos = lseek (filedesc, offset, SEEK_CUR);
919 fstr->current_pos = max (fstr->starting_pos, 0);
923 fstr->end_pos = fstr->starting_pos + count;
924 lstr->flags |= LSTREAM_FL_CLOSE_AT_DISKSAVE;
925 XSETLSTREAM (obj, lstr);
930 make_filedesc_input_stream (int filedesc, int offset, int count, int flags)
932 return make_filedesc_stream_1 (filedesc, offset, count, flags, "r");
936 make_filedesc_output_stream (int filedesc, int offset, int count, int flags)
938 return make_filedesc_stream_1 (filedesc, offset, count, flags, "w");
942 filedesc_reader (Lstream *stream, unsigned char *data, size_t size)
945 struct filedesc_stream *str = FILEDESC_STREAM_DATA (stream);
946 if (str->end_pos >= 0)
947 size = min (size, (size_t) (str->end_pos - str->current_pos));
948 nread = str->allow_quit ?
949 read_allowing_quit (str->fd, data, size) :
950 read (str->fd, data, size);
952 str->current_pos += nread;
957 errno_would_block_p (int val)
960 if (val == EWOULDBLOCK)
971 filedesc_writer (Lstream *stream, const unsigned char *data, size_t size)
973 struct filedesc_stream *str = FILEDESC_STREAM_DATA (stream);
975 int need_newline = 0;
977 /* This function would be simple if it were not for the blasted
978 PTY max-bytes stuff. Why the hell can't they just have written
979 the PTY drivers right so this problem doesn't exist?
981 Maybe all the PTY crap here should be moved into another stream
982 that does nothing but periodically insert EOF's as necessary. */
983 if (str->pty_flushing)
985 /* To make life easy, only send out one line at the most. */
986 const unsigned char *ptr;
988 ptr = (const unsigned char *) memchr (data, '\n', size);
993 if (ptr - data >= str->pty_max_bytes - str->chars_sans_newline)
995 ptr = data + str->pty_max_bytes - str->chars_sans_newline;
1001 /**** start of non-PTY-crap ****/
1003 retval = str->allow_quit ?
1004 write_allowing_quit (str->fd, data, size) :
1005 write (str->fd, data, size);
1008 if (retval < 0 && errno_would_block_p (errno) && str->blocked_ok)
1010 str->blocking_error_p = 1;
1013 str->blocking_error_p = 0;
1016 /**** end non-PTY-crap ****/
1018 if (str->pty_flushing)
1020 str->chars_sans_newline += retval;
1021 /* Note that a newline was not among the bytes written out.
1022 Add to the number of non-newline bytes written out,
1023 and flush with an EOF if necessary. Be careful to
1024 keep track of write errors as we go along and look
1025 out for EWOULDBLOCK. */
1026 if (str->chars_sans_newline >= str->pty_max_bytes)
1028 ssize_t retval2 = str->allow_quit ?
1029 write_allowing_quit (str->fd, &str->eof_char, 1) :
1030 write (str->fd, &str->eof_char, 1);
1033 str->chars_sans_newline = 0;
1034 else if (retval2 < 0)
1036 /* Error writing the EOF char. If nothing got written,
1037 then treat this as an error -- either return an error
1038 condition or set the blocking-error flag. */
1041 if (errno_would_block_p (errno) && str->blocked_ok)
1043 str->blocking_error_p = 1;
1055 /* The need_newline flag is necessary because otherwise when the
1056 first byte is a newline, we'd get stuck never writing anything
1057 in pty-flushing mode. */
1061 ssize_t retval2 = str->allow_quit ?
1062 write_allowing_quit (str->fd, &nl, 1) :
1063 write (str->fd, &nl, 1);
1067 str->chars_sans_newline = 0;
1070 else if (retval2 < 0)
1072 /* Error writing the newline char. If nothing got written,
1073 then treat this as an error -- either return an error
1074 condition or set the blocking-error flag. */
1077 if (errno_would_block_p (errno) && str->blocked_ok)
1079 str->blocking_error_p = 1;
1094 filedesc_rewinder (Lstream *stream)
1096 struct filedesc_stream *str = FILEDESC_STREAM_DATA (stream);
1097 if (str->starting_pos < 0 ||
1098 lseek (FILEDESC_STREAM_DATA (stream)->fd, str->starting_pos,
1103 str->current_pos = str->starting_pos;
1109 filedesc_seekable_p (Lstream *stream)
1111 struct filedesc_stream *str = FILEDESC_STREAM_DATA (stream);
1112 if (str->starting_pos < 0)
1118 if (fstat (str->fd, &lestat) < 0)
1120 return S_ISREG (lestat.st_mode);
1125 filedesc_closer (Lstream *stream)
1127 struct filedesc_stream *str = FILEDESC_STREAM_DATA (stream);
1129 return close (str->fd);
1135 filedesc_was_blocked_p (Lstream *stream)
1137 struct filedesc_stream *str = FILEDESC_STREAM_DATA (stream);
1138 return str->blocking_error_p;
1142 filedesc_stream_set_pty_flushing (Lstream *stream, int pty_max_bytes,
1145 struct filedesc_stream *str = FILEDESC_STREAM_DATA (stream);
1146 str->pty_max_bytes = pty_max_bytes;
1147 str->eof_char = eof_char;
1148 str->pty_flushing = 1;
1152 filedesc_stream_fd (Lstream *stream)
1154 struct filedesc_stream *str = FILEDESC_STREAM_DATA (stream);
1158 /*********** read from a Lisp string ***********/
1160 #define LISP_STRING_STREAM_DATA(stream) LSTREAM_TYPE_DATA (stream, lisp_string)
1162 struct lisp_string_stream
1165 Bytecount init_offset;
1166 Bytecount offset, end;
1169 DEFINE_LSTREAM_IMPLEMENTATION ("lisp-string", lstream_lisp_string,
1170 sizeof (struct lisp_string_stream));
1173 make_lisp_string_input_stream (Lisp_Object string, Bytecount offset,
1178 struct lisp_string_stream *str;
1180 CHECK_STRING (string);
1182 len = XSTRING_LENGTH (string) - offset;
1183 assert (offset >= 0);
1185 assert (offset + len <= XSTRING_LENGTH (string));
1187 lstr = Lstream_new (lstream_lisp_string, "r");
1188 str = LISP_STRING_STREAM_DATA (lstr);
1189 str->offset = offset;
1190 str->end = offset + len;
1191 str->init_offset = offset;
1193 XSETLSTREAM (obj, lstr);
1198 lisp_string_reader (Lstream *stream, unsigned char *data, size_t size)
1200 struct lisp_string_stream *str = LISP_STRING_STREAM_DATA (stream);
1201 /* Don't lose if the string shrank past us ... */
1202 Bytecount offset = min (str->offset, XSTRING_LENGTH (str->obj));
1203 Bufbyte *strstart = XSTRING_DATA (str->obj);
1204 Bufbyte *start = strstart + offset;
1206 /* ... or if someone changed the string and we ended up in the
1207 middle of a character. */
1208 /* Being in the middle of a character is `normal' unless
1209 LSTREAM_NO_PARTIAL_CHARS - mrb */
1210 if (stream->flags & LSTREAM_FL_NO_PARTIAL_CHARS)
1211 VALIDATE_CHARPTR_BACKWARD (start);
1212 offset = start - strstart;
1213 size = min (size, (size_t) (str->end - offset));
1214 memcpy (data, start, size);
1215 str->offset = offset + size;
1220 lisp_string_rewinder (Lstream *stream)
1222 struct lisp_string_stream *str = LISP_STRING_STREAM_DATA (stream);
1223 int pos = str->init_offset;
1226 /* Don't lose if the string shrank past us ... */
1227 pos = min (pos, XSTRING_LENGTH (str->obj));
1228 /* ... or if someone changed the string and we ended up in the
1229 middle of a character. */
1231 Bufbyte *strstart = XSTRING_DATA (str->obj);
1232 Bufbyte *start = strstart + pos;
1233 VALIDATE_CHARPTR_BACKWARD (start);
1234 pos = start - strstart;
1241 lisp_string_marker (Lisp_Object stream)
1243 struct lisp_string_stream *str = LISP_STRING_STREAM_DATA (XLSTREAM (stream));
1247 /*********** a fixed buffer ***********/
1249 #define FIXED_BUFFER_STREAM_DATA(stream) \
1250 LSTREAM_TYPE_DATA (stream, fixed_buffer)
1252 struct fixed_buffer_stream
1254 const unsigned char *inbuf;
1255 unsigned char *outbuf;
1260 DEFINE_LSTREAM_IMPLEMENTATION ("fixed-buffer", lstream_fixed_buffer,
1261 sizeof (struct fixed_buffer_stream));
1264 make_fixed_buffer_input_stream (const void *buf, size_t size)
1267 Lstream *lstr = Lstream_new (lstream_fixed_buffer, "r");
1268 struct fixed_buffer_stream *str = FIXED_BUFFER_STREAM_DATA (lstr);
1269 str->inbuf = (const unsigned char *) buf;
1271 XSETLSTREAM (obj, lstr);
1276 make_fixed_buffer_output_stream (void *buf, size_t size)
1279 Lstream *lstr = Lstream_new (lstream_fixed_buffer, "w");
1280 struct fixed_buffer_stream *str = FIXED_BUFFER_STREAM_DATA (lstr);
1281 str->outbuf = (unsigned char *) buf;
1283 XSETLSTREAM (obj, lstr);
1288 fixed_buffer_reader (Lstream *stream, unsigned char *data, size_t size)
1290 struct fixed_buffer_stream *str = FIXED_BUFFER_STREAM_DATA (stream);
1291 size = min (size, str->size - str->offset);
1292 memcpy (data, str->inbuf + str->offset, size);
1293 str->offset += size;
1298 fixed_buffer_writer (Lstream *stream, const unsigned char *data, size_t size)
1300 struct fixed_buffer_stream *str = FIXED_BUFFER_STREAM_DATA (stream);
1301 if (str->offset == str->size)
1303 /* If we're at the end, just throw away the data and pretend
1304 we wrote all of it. If we return 0, then the lstream routines
1305 will try again and again to write it out. */
1308 size = min (size, str->size - str->offset);
1309 memcpy (str->outbuf + str->offset, data, size);
1310 str->offset += size;
1315 fixed_buffer_rewinder (Lstream *stream)
1317 FIXED_BUFFER_STREAM_DATA (stream)->offset = 0;
1321 const unsigned char *
1322 fixed_buffer_input_stream_ptr (Lstream *stream)
1324 assert (stream->imp == lstream_fixed_buffer);
1325 return FIXED_BUFFER_STREAM_DATA (stream)->inbuf;
1329 fixed_buffer_output_stream_ptr (Lstream *stream)
1331 assert (stream->imp == lstream_fixed_buffer);
1332 return FIXED_BUFFER_STREAM_DATA (stream)->outbuf;
1335 /*********** write to a resizing buffer ***********/
1337 #define RESIZING_BUFFER_STREAM_DATA(stream) \
1338 LSTREAM_TYPE_DATA (stream, resizing_buffer)
1340 struct resizing_buffer_stream
1348 DEFINE_LSTREAM_IMPLEMENTATION ("resizing-buffer", lstream_resizing_buffer,
1349 sizeof (struct resizing_buffer_stream));
1352 make_resizing_buffer_output_stream (void)
1355 XSETLSTREAM (obj, Lstream_new (lstream_resizing_buffer, "w"));
1360 resizing_buffer_writer (Lstream *stream, const unsigned char *data, size_t size)
1362 struct resizing_buffer_stream *str = RESIZING_BUFFER_STREAM_DATA (stream);
1363 DO_REALLOC (str->buf, str->allocked, str->stored + size, unsigned char);
1364 memcpy (str->buf + str->stored, data, size);
1365 str->stored += size;
1366 str->max_stored = max (str->max_stored, str->stored);
1371 resizing_buffer_rewinder (Lstream *stream)
1373 RESIZING_BUFFER_STREAM_DATA (stream)->stored = 0;
1378 resizing_buffer_closer (Lstream *stream)
1380 struct resizing_buffer_stream *str = RESIZING_BUFFER_STREAM_DATA (stream);
1390 resizing_buffer_stream_ptr (Lstream *stream)
1392 return RESIZING_BUFFER_STREAM_DATA (stream)->buf;
1395 /*********** write to an unsigned-char dynarr ***********/
1397 /* Note: If you have a dynarr whose type is not unsigned_char_dynarr
1398 but which is really just an unsigned_char_dynarr (e.g. its type
1399 is Bufbyte or Extbyte), just cast to unsigned_char_dynarr. */
1401 #define DYNARR_STREAM_DATA(stream) \
1402 LSTREAM_TYPE_DATA (stream, dynarr)
1404 struct dynarr_stream
1406 unsigned_char_dynarr *dyn;
1409 DEFINE_LSTREAM_IMPLEMENTATION ("dynarr", lstream_dynarr,
1410 sizeof (struct dynarr_stream));
1413 make_dynarr_output_stream (unsigned_char_dynarr *dyn)
1416 XSETLSTREAM (obj, Lstream_new (lstream_dynarr, "w"));
1417 DYNARR_STREAM_DATA (XLSTREAM (obj))->dyn = dyn;
1422 dynarr_writer (Lstream *stream, const unsigned char *data, size_t size)
1424 struct dynarr_stream *str = DYNARR_STREAM_DATA (stream);
1425 Dynarr_add_many (str->dyn, data, size);
1430 dynarr_rewinder (Lstream *stream)
1432 Dynarr_reset (DYNARR_STREAM_DATA (stream)->dyn);
1437 dynarr_closer (Lstream *stream)
1442 /************ read from or write to a Lisp buffer ************/
1444 /* Note: Lisp-buffer read streams never return partial characters,
1445 and Lisp-buffer write streams expect to never get partial
1448 #define LISP_BUFFER_STREAM_DATA(stream) \
1449 LSTREAM_TYPE_DATA (stream, lisp_buffer)
1451 struct lisp_buffer_stream
1454 Lisp_Object orig_start;
1455 /* we use markers to properly deal with insertion/deletion */
1456 Lisp_Object start, end;
1460 DEFINE_LSTREAM_IMPLEMENTATION ("lisp-buffer", lstream_lisp_buffer,
1461 sizeof (struct lisp_buffer_stream));
1464 make_lisp_buffer_stream_1 (struct buffer *buf, Bufpos start, Bufpos end,
1465 int flags, const char *mode)
1469 struct lisp_buffer_stream *str;
1471 int reading = !strcmp (mode, "r");
1473 /* Make sure the luser didn't pass "w" in. */
1474 if (!strcmp (mode, "w"))
1477 if (flags & LSTR_IGNORE_ACCESSIBLE)
1479 bmin = BUF_BEG (buf);
1484 bmin = BUF_BEGV (buf);
1485 bmax = BUF_ZV (buf);
1492 assert (bmin <= start);
1493 assert (start <= bmax);
1496 assert (bmin <= end);
1497 assert (end <= bmax);
1498 assert (start <= end);
1501 lstr = Lstream_new (lstream_lisp_buffer, mode);
1502 str = LISP_BUFFER_STREAM_DATA (lstr);
1507 XSETBUFFER (buffer, buf);
1508 marker = Fmake_marker ();
1509 Fset_marker (marker, make_int (start), buffer);
1510 str->start = marker;
1511 marker = Fmake_marker ();
1512 Fset_marker (marker, make_int (start), buffer);
1513 str->orig_start = marker;
1516 marker = Fmake_marker ();
1517 Fset_marker (marker, make_int (end), buffer);
1522 str->buffer = buffer;
1525 XSETLSTREAM (obj, lstr);
1530 make_lisp_buffer_input_stream (struct buffer *buf, Bufpos start, Bufpos end,
1533 return make_lisp_buffer_stream_1 (buf, start, end, flags, "r");
1537 make_lisp_buffer_output_stream (struct buffer *buf, Bufpos pos, int flags)
1539 Lisp_Object lstr = make_lisp_buffer_stream_1 (buf, pos, 0, flags, "wc");
1541 Lstream_set_character_mode (XLSTREAM (lstr));
1546 lisp_buffer_reader (Lstream *stream, unsigned char *data, size_t size)
1548 struct lisp_buffer_stream *str = LISP_BUFFER_STREAM_DATA (stream);
1549 unsigned char *orig_data = data;
1552 struct buffer *buf = XBUFFER (str->buffer);
1554 if (!BUFFER_LIVE_P (buf))
1555 return 0; /* Fut. */
1557 /* NOTE: We do all our operations in Bytind's.
1558 Keep in mind that SIZE is a value in bytes, not chars. */
1560 start = bi_marker_position (str->start);
1561 end = bi_marker_position (str->end);
1562 if (!(str->flags & LSTR_IGNORE_ACCESSIBLE))
1564 start = bytind_clip_to_bounds (BI_BUF_BEGV (buf), start,
1566 end = bytind_clip_to_bounds (BI_BUF_BEGV (buf), end,
1570 size = min (size, (size_t) (end - start));
1572 /* We cannot return a partial character. */
1573 VALIDATE_BYTIND_BACKWARD (buf, end);
1580 if (str->flags & LSTR_IGNORE_ACCESSIBLE)
1581 ceil = BI_BUF_CEILING_OF_IGNORE_ACCESSIBLE (buf, start);
1583 ceil = BI_BUF_CEILING_OF (buf, start);
1584 chunk = min (ceil, end) - start;
1585 memcpy (data, BI_BUF_BYTE_ADDRESS (buf, start), chunk);
1590 if (EQ (buf->selective_display, Qt) && str->flags & LSTR_SELECTIVE)
1592 /* What a kludge. What a kludge. What a kludge. */
1594 for (p = orig_data; p < data; p++)
1599 set_bi_marker_position (str->start, end);
1600 return data - orig_data;
1604 lisp_buffer_writer (Lstream *stream, const unsigned char *data, size_t size)
1606 struct lisp_buffer_stream *str = LISP_BUFFER_STREAM_DATA (stream);
1608 struct buffer *buf = XBUFFER (str->buffer);
1610 if (!BUFFER_LIVE_P (buf))
1611 return 0; /* Fut. */
1613 pos = marker_position (str->start);
1614 pos += buffer_insert_raw_string_1 (buf, pos, data, size, 0);
1615 set_marker_position (str->start, pos);
1620 lisp_buffer_rewinder (Lstream *stream)
1622 struct lisp_buffer_stream *str =
1623 LISP_BUFFER_STREAM_DATA (stream);
1624 struct buffer *buf = XBUFFER (str->buffer);
1625 long pos = marker_position (str->orig_start);
1626 if (!BUFFER_LIVE_P (buf))
1627 return -1; /* Fut. */
1628 if (pos > BUF_ZV (buf))
1630 if (pos < marker_position (str->orig_start))
1631 pos = marker_position (str->orig_start);
1632 if (MARKERP (str->end) && pos > marker_position (str->end))
1633 pos = marker_position (str->end);
1634 set_marker_position (str->start, pos);
1639 lisp_buffer_marker (Lisp_Object stream)
1641 struct lisp_buffer_stream *str =
1642 LISP_BUFFER_STREAM_DATA (XLSTREAM (stream));
1644 mark_object (str->start);
1645 mark_object (str->end);
1650 lisp_buffer_stream_startpos (Lstream *stream)
1652 return marker_position (LISP_BUFFER_STREAM_DATA (stream)->start);
1656 /************************************************************************/
1657 /* initialization */
1658 /************************************************************************/
1661 lstream_type_create (void)
1663 LSTREAM_HAS_METHOD (stdio, reader);
1664 LSTREAM_HAS_METHOD (stdio, writer);
1665 LSTREAM_HAS_METHOD (stdio, rewinder);
1666 LSTREAM_HAS_METHOD (stdio, seekable_p);
1667 LSTREAM_HAS_METHOD (stdio, flusher);
1668 LSTREAM_HAS_METHOD (stdio, closer);
1670 LSTREAM_HAS_METHOD (filedesc, reader);
1671 LSTREAM_HAS_METHOD (filedesc, writer);
1672 LSTREAM_HAS_METHOD (filedesc, was_blocked_p);
1673 LSTREAM_HAS_METHOD (filedesc, rewinder);
1674 LSTREAM_HAS_METHOD (filedesc, seekable_p);
1675 LSTREAM_HAS_METHOD (filedesc, closer);
1677 LSTREAM_HAS_METHOD (lisp_string, reader);
1678 LSTREAM_HAS_METHOD (lisp_string, rewinder);
1679 LSTREAM_HAS_METHOD (lisp_string, marker);
1681 LSTREAM_HAS_METHOD (fixed_buffer, reader);
1682 LSTREAM_HAS_METHOD (fixed_buffer, writer);
1683 LSTREAM_HAS_METHOD (fixed_buffer, rewinder);
1685 LSTREAM_HAS_METHOD (resizing_buffer, writer);
1686 LSTREAM_HAS_METHOD (resizing_buffer, rewinder);
1687 LSTREAM_HAS_METHOD (resizing_buffer, closer);
1689 LSTREAM_HAS_METHOD (dynarr, writer);
1690 LSTREAM_HAS_METHOD (dynarr, rewinder);
1691 LSTREAM_HAS_METHOD (dynarr, closer);
1693 LSTREAM_HAS_METHOD (lisp_buffer, reader);
1694 LSTREAM_HAS_METHOD (lisp_buffer, writer);
1695 LSTREAM_HAS_METHOD (lisp_buffer, rewinder);
1696 LSTREAM_HAS_METHOD (lisp_buffer, marker);
1700 reinit_vars_of_lstream (void)
1704 for (i = 0; i < countof (Vlstream_free_list); i++)
1706 Vlstream_free_list[i] = Qnil;
1707 staticpro_nodump (&Vlstream_free_list[i]);
1712 vars_of_lstream (void)
1714 INIT_LRECORD_IMPLEMENTATION (lstream);
1716 reinit_vars_of_lstream ();