(U-000262B7): New character; use `<-denotational' for A-IWDSU+7758.
[chise/xemacs-chise.git.1] / src / lstream.h
1 /* Generic stream implementation -- header file.
2    Copyright (C) 1995 Free Software Foundation, Inc.
3    Copyright (C) 1996 Ben Wing.
4
5 This file is part of XEmacs.
6
7 XEmacs is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by the
9 Free Software Foundation; either version 2, or (at your option) any
10 later version.
11
12 XEmacs is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15 for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with XEmacs; see the file COPYING.  If not, write to
19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA.  */
21
22 /* Synched up with: Not in FSF. */
23
24 /* Written by Ben Wing. */
25
26 #ifndef INCLUDED_lstream_h_
27 #define INCLUDED_lstream_h_
28
29 /************************************************************************/
30 /*                     definition of Lstream object                     */
31 /************************************************************************/
32
33 DECLARE_LRECORD (lstream, struct lstream);
34 #define XLSTREAM(x) XRECORD (x, lstream, struct lstream)
35 #define XSETLSTREAM(x, p) XSETRECORD (x, p, lstream)
36 #define LSTREAMP(x) RECORDP (x, lstream)
37 /* #define CHECK_LSTREAM(x) CHECK_RECORD (x, lstream)
38    Lstream pointers should never escape to the Lisp level, so
39    functions should not be doing this. */
40
41 #ifndef EOF
42 #define EOF (-1)
43 #endif
44
45 /* Typedef specifying a count of bytes in a data block to be written
46    out or read in, using Lstream_read(), Lstream_write(), and related
47    functions.  This MUST BE SIGNED, since it also is used in functions
48    that return the number of bytes actually read to or written from in
49    an operation, and these functions can return -1 to signal error.
50    
51    Note that the standard Unix read() and write() functions define the
52    count going in as a size_t, which is UNSIGNED, and the count going
53    out as an ssize_t, which is SIGNED.  This is a horrible design
54    flaw.  Not only is it highly likely to lead to logic errors when a
55    -1 gets interpreted as a large positive number, but operations are
56    bound to fail in all sorts of horrible ways when a number in the
57    upper-half of the size_t range is passed in -- this number is
58    unrepresentable as an ssize_t, so code that checks to see how many
59    bytes are actually written (which is mandatory if you are dealing
60    with certain types of devices) will get completely screwed up.
61 */
62
63 typedef EMACS_INT Lstream_data_count;
64
65 typedef enum lstream_buffering
66 {
67   /* No buffering. */
68   LSTREAM_UNBUFFERED,
69   /* Buffer until a '\n' character is reached. */
70   LSTREAM_LINE_BUFFERED,
71   /* Buffer in standard-size (i.e. 512-byte) blocks. */
72   LSTREAM_BLOCK_BUFFERED,
73   /* Buffer in blocks of a specified size. */
74   LSTREAM_BLOCKN_BUFFERED,
75   /* Buffer until the stream is closed (only applies to write-only
76      streams).  Only one call to the stream writer will be made,
77      and that is when the stream is closed. */
78   LSTREAM_UNLIMITED
79 } Lstream_buffering;
80
81 /* Methods defining how this stream works.  Some may be undefined. */
82
83 /* We do not implement the seek/tell paradigm.  I tried to do that,
84    but getting the semantics right in the presence of buffering is
85    extremely tricky and very error-prone and basically not worth it.
86    This is especially the case with complicated streams like
87    decoding streams -- the seek pointer in this case can't be a single
88    integer but has to be a whole complicated structure that records
89    all of the stream's state at the time.
90
91    Rewind semantics are generally easy to implement, so we do provide
92    a rewind method.  Even rewind() may not be available on a stream,
93    however -- e.g. on process output. */
94
95 typedef struct lstream_implementation
96 {
97   const char *name;
98   Lstream_data_count size; /* Number of additional bytes to be
99                               allocated with this stream.  Access this
100                               data using Lstream_data(). */
101   /* Read some data from the stream's end and store it into DATA, which
102      can hold SIZE bytes.  Return the number of bytes read.  A return
103      value of 0 means no bytes can be read at this time.  This may
104      be because of an EOF, or because there is a granularity greater
105      than one byte that the stream imposes on the returned data, and
106      SIZE is less than this granularity. (This will happen frequently
107      for streams that need to return whole characters, because
108      Lstream_read() calls the reader function repeatedly until it
109      has the number of bytes it wants or until 0 is returned.)
110      The lstream functions do not treat a 0 return as EOF or do
111      anything special; however, the calling function will interpret
112      any 0 it gets back as EOF.  This will normally not happen unless
113      the caller calls Lstream_read() with a very small size.
114
115      This function can be NULL if the stream is output-only. */
116   /* The omniscient mly, blinded by the irresistible thrall of Common
117      Lisp, thinks that it is bogus that the types and implementations
118      of input and output streams are the same. */
119   Lstream_data_count (*reader) (Lstream *stream, unsigned char *data,
120                                 Lstream_data_count size);
121   /* Send some data to the stream's end.  Data to be sent is in DATA
122      and is SIZE bytes.  Return the number of bytes sent.  This
123      function can send and return fewer bytes than is passed in; in
124      that case, the function will just be called again until there is
125      no data left or 0 is returned.  A return value of 0 means that no
126      more data can be currently stored, but there is no error; the
127      data will be squirrelled away until the writer can accept
128      data. (This is useful, e.g., of you're dealing with a
129      non-blocking file descriptor and are getting EWOULDBLOCK errors.)
130      This function can be NULL if the stream is input-only. */
131   Lstream_data_count (*writer) (Lstream *stream, const unsigned char *data,
132                                 Lstream_data_count size);
133   /* Return non-zero if the last write operation on the stream resulted
134      in an attempt to block (EWOULDBLOCK). If this method does not
135      exists, the implementation returns 0 */
136   int (*was_blocked_p) (Lstream *stream);
137   /* Rewind the stream.  If this is NULL, the stream is not seekable. */
138   int (*rewinder) (Lstream *stream);
139   /* Indicate whether this stream is seekable -- i.e. it can be rewound.
140      This method is ignored if the stream does not have a rewind
141      method.  If this method is not present, the result is determined
142      by whether a rewind method is present. */
143   int (*seekable_p) (Lstream *stream);
144   /* Perform any additional operations necessary to flush the
145      data in this stream. */
146   int (*flusher) (Lstream *stream);
147   /* Perform any additional operations necessary to close this
148      stream down.  May be NULL.  This function is called when
149      Lstream_close() is called or when the stream is garbage-
150      collected.  When this function is called, all pending data
151      in the stream will already have been written out. */
152   int (*closer) (Lstream *stream);
153   /* Mark this object for garbage collection.  Same semantics as
154      a standard Lisp_Object marker.  This function can be NULL. */
155   Lisp_Object (*marker) (Lisp_Object lstream);
156 } Lstream_implementation;
157
158 #define DEFINE_LSTREAM_IMPLEMENTATION(name,c_name,size) \
159  Lstream_implementation c_name[1] =                     \
160    { { (name), (size) } }
161
162 #define LSTREAM_FL_IS_OPEN              1
163 #define LSTREAM_FL_READ                 2
164 #define LSTREAM_FL_WRITE                4
165 #define LSTREAM_FL_NO_PARTIAL_CHARS     8
166 #define LSTREAM_FL_CLOSE_AT_DISKSAVE    16
167
168 struct lstream
169 {
170   struct lcrecord_header header;
171   const Lstream_implementation *imp; /* methods for this stream */
172   Lstream_buffering buffering; /* type of buffering in use */
173   Lstream_data_count buffering_size; /* number of bytes buffered */
174
175   unsigned char *in_buffer; /* holds characters read from stream end */
176   Lstream_data_count in_buffer_size; /* allocated size of buffer */
177   Lstream_data_count in_buffer_current; /* number of characters in buffer */
178   Lstream_data_count in_buffer_ind; /* pointer to next character to
179                                        take from buffer */
180
181   unsigned char *out_buffer; /* holds characters to write to stream end */
182   Lstream_data_count out_buffer_size; /* allocated size of buffer */
183   Lstream_data_count out_buffer_ind; /* pointer to next buffer spot to
184                                         write a character */
185
186   /* The unget buffer is more or less a stack -- things get pushed
187      onto the end and read back from the end.  Lstream_read()
188      basically reads backwards from the end to get stuff; Lstream_unread()
189      similarly has to push the data on backwards. */
190   unsigned char *unget_buffer; /* holds characters pushed back onto input */
191   Lstream_data_count unget_buffer_size; /* allocated size of buffer */
192   Lstream_data_count unget_buffer_ind; /* pointer to next buffer spot
193                                           to write a character */
194
195   Lstream_data_count byte_count;
196   int flags;
197   max_align_t data[1];
198 };
199
200 #define LSTREAM_TYPE_P(lstr, type) \
201   ((lstr)->imp == lstream_##type)
202
203 #ifdef ERROR_CHECK_TYPECHECK
204 INLINE_HEADER struct lstream *
205 error_check_lstream_type (struct lstream *stream,
206                           const Lstream_implementation *imp);
207 INLINE_HEADER struct lstream *
208 error_check_lstream_type (struct lstream *stream,
209                           const Lstream_implementation *imp)
210 {
211   assert (stream->imp == imp);
212   return stream;
213 }
214 # define LSTREAM_TYPE_DATA(lstr, type) \
215   ((struct type##_stream *) \
216     Lstream_data (error_check_lstream_type(lstr, lstream_##type)))
217 #else
218 # define LSTREAM_TYPE_DATA(lstr, type)          \
219   ((struct type##_stream *) Lstream_data (lstr))
220 #endif
221
222 /* Declare that lstream-type TYPE has method M; used in
223    initialization routines */
224 #define LSTREAM_HAS_METHOD(type, m) \
225   (lstream_##type->m = type##_##m)
226
227
228 Lstream *Lstream_new (const Lstream_implementation *imp,
229                       const char *mode);
230 void Lstream_reopen (Lstream *lstr);
231 void Lstream_set_buffering (Lstream *lstr, Lstream_buffering buffering,
232                             int buffering_size);
233 int Lstream_flush (Lstream *lstr);
234 int Lstream_flush_out (Lstream *lstr);
235 int Lstream_fputc (Lstream *lstr, int c);
236 int Lstream_fgetc (Lstream *lstr);
237 void Lstream_fungetc (Lstream *lstr, int c);
238 Lstream_data_count Lstream_read (Lstream *lstr, void *data,
239                                  Lstream_data_count size);
240 Lstream_data_count Lstream_write (Lstream *lstr, const void *data,
241                                   Lstream_data_count size);
242 int Lstream_was_blocked_p (Lstream *lstr);
243 void Lstream_unread (Lstream *lstr, const void *data, Lstream_data_count size);
244 int Lstream_rewind (Lstream *lstr);
245 int Lstream_seekable_p (Lstream *lstr);
246 int Lstream_close (Lstream *lstr);
247 void Lstream_delete (Lstream *lstr);
248 void Lstream_set_character_mode (Lstream *str);
249
250 /* Call the function equivalent if the out buffer is full.  Otherwise,
251    add to the end of the out buffer and, if line buffering is called for
252    and the character marks the end of a line, write out the buffer. */
253
254 #define Lstream_putc(stream, c)                                         \
255   ((stream)->out_buffer_ind >= (stream)->out_buffer_size ?              \
256    Lstream_fputc (stream, c) :                                          \
257    ((stream)->out_buffer[(stream)->out_buffer_ind++] =                  \
258     (unsigned char) (c),                                                \
259     (stream)->byte_count++,                                             \
260     (stream)->buffering == LSTREAM_LINE_BUFFERED &&                     \
261     (stream)->out_buffer[(stream)->out_buffer_ind - 1] == '\n' ?        \
262     Lstream_flush_out (stream) : 0))
263
264 /* Retrieve from unget buffer if there are any characters there;
265    else retrieve from in buffer if there's anything there;
266    else call the function equivalent */
267 #define Lstream_getc(stream)                                            \
268   ((stream)->unget_buffer_ind > 0 ?                                     \
269    ((stream)->byte_count++,                                             \
270     (stream)->unget_buffer[--(stream)->unget_buffer_ind]) :             \
271    (stream)->in_buffer_ind < (stream)->in_buffer_current ?              \
272     ((stream)->byte_count++,                                            \
273      (stream)->in_buffer[(stream)->in_buffer_ind++]) :                  \
274     Lstream_fgetc (stream))
275
276 /* Add to the end if it won't overflow buffer; otherwise call the
277    function equivalent */
278 #define Lstream_ungetc(stream, c)                                       \
279   ((stream)->unget_buffer_ind >= (stream)->unget_buffer_size ?          \
280    Lstream_fungetc (stream, c) :                                        \
281    (void) ((stream)->byte_count--,                                      \
282    ((stream)->unget_buffer[(stream)->unget_buffer_ind++] =              \
283     (unsigned char) (c))))
284
285 #define Lstream_data(stream) ((void *) ((stream)->data))
286 #define Lstream_byte_count(stream) ((stream)->byte_count)
287
288 \f
289 /************************************************************************/
290 /*             working with an Lstream as a stream of Emchars           */
291 /************************************************************************/
292
293 #ifdef MULE
294
295 #ifndef BYTE_ASCII_P
296 #include "multibyte.h"
297 #endif
298
299 #ifndef CHAR_ASCII_P
300 #include "character.h"
301 #endif
302
303 INLINE_HEADER Emchar Lstream_get_emchar (Lstream *stream);
304 INLINE_HEADER Emchar
305 Lstream_get_emchar (Lstream *stream)
306 {
307   int c = Lstream_getc (stream);
308   return (c < 0x80              /* c == EOF || BYTE_ASCII_P (c) */
309           ? (Emchar) c
310           : Lstream_get_emchar_1 (stream, c));
311 }
312
313 INLINE_HEADER int Lstream_put_emchar (Lstream *stream, Emchar ch);
314 INLINE_HEADER int
315 Lstream_put_emchar (Lstream *stream, Emchar ch)
316 {
317   return CHAR_ASCII_P (ch) ?
318     Lstream_putc (stream, ch) :
319     Lstream_fput_emchar (stream, ch);
320 }
321
322 INLINE_HEADER void Lstream_unget_emchar (Lstream *stream, Emchar ch);
323 INLINE_HEADER void
324 Lstream_unget_emchar (Lstream *stream, Emchar ch)
325 {
326   if (CHAR_ASCII_P (ch))
327     Lstream_ungetc (stream, ch);
328   else
329     Lstream_funget_emchar (stream, ch);
330 }
331 #else /* not MULE */
332
333 # define Lstream_get_emchar(stream) Lstream_getc (stream)
334 # define Lstream_put_emchar(stream, ch) Lstream_putc (stream, ch)
335 # define Lstream_unget_emchar(stream, ch) Lstream_ungetc (stream, ch)
336
337 #endif /* not MULE */
338
339 \f
340 /************************************************************************/
341 /*                        Lstream implementations                       */
342 /************************************************************************/
343
344 /* Flags we can pass to the filedesc and stdio streams. */
345
346 /* If set, close the descriptor or FILE * when the stream is closed. */
347 #define LSTR_CLOSING 1
348
349 /* If set, allow quitting out of the actual I/O. */
350 #define LSTR_ALLOW_QUIT 2
351
352 /* If set and filedesc_stream_set_pty_flushing() has been called
353    on the stream, do not send more than pty_max_bytes on a single
354    line without flushing the data out using the eof_char. */
355 #define LSTR_PTY_FLUSHING 4
356
357 /* If set, an EWOULDBLOCK error is not treated as an error but
358    simply causes the write function to return 0 as the number
359    of bytes written out. */
360 #define LSTR_BLOCKED_OK 8
361
362 Lisp_Object make_stdio_input_stream (FILE *stream, int flags);
363 Lisp_Object make_stdio_output_stream (FILE *stream, int flags);
364 Lisp_Object make_filedesc_input_stream (int filedesc, int offset, int count,
365                                         int flags);
366 Lisp_Object make_filedesc_output_stream (int filedesc, int offset, int count,
367                                          int flags);
368 void filedesc_stream_set_pty_flushing (Lstream *stream,
369                                        int pty_max_bytes,
370                                        Bufbyte eof_char);
371 int filedesc_stream_fd (Lstream *stream);
372 Lisp_Object make_lisp_string_input_stream (Lisp_Object string,
373                                            Bytecount offset,
374                                            Bytecount len);
375 Lisp_Object make_fixed_buffer_input_stream (const void *buf,
376                                             Lstream_data_count size);
377 Lisp_Object make_fixed_buffer_output_stream (void *buf,
378                                              Lstream_data_count size);
379 const unsigned char *fixed_buffer_input_stream_ptr (Lstream *stream);
380 unsigned char *fixed_buffer_output_stream_ptr (Lstream *stream);
381 Lisp_Object make_resizing_buffer_output_stream (void);
382 unsigned char *resizing_buffer_stream_ptr (Lstream *stream);
383 Lisp_Object make_dynarr_output_stream (unsigned_char_dynarr *dyn);
384 #define LSTR_SELECTIVE 1
385 #define LSTR_IGNORE_ACCESSIBLE 2
386 Lisp_Object make_lisp_buffer_input_stream (struct buffer *buf, Bufpos start,
387                                            Bufpos end, int flags);
388 Lisp_Object make_lisp_buffer_output_stream (struct buffer *buf, Bufpos pos,
389                                             int flags);
390 Bufpos lisp_buffer_stream_startpos (Lstream *stream);
391
392 #endif /* INCLUDED_lstream_h_ */