Mercurial > hg > xemacs-beta
comparison src/lstream.h @ 0:376386a54a3c r19-14
Import from CVS: tag r19-14
author | cvs |
---|---|
date | Mon, 13 Aug 2007 08:45:50 +0200 |
parents | |
children | 131b0175ea99 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:376386a54a3c |
---|---|
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 _XEMACS_LSTREAM_H_ | |
27 #define _XEMACS_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 enum lstream_buffering | |
46 { | |
47 /* No buffering. */ | |
48 LSTREAM_UNBUFFERED, | |
49 /* Buffer until a '\n' character is reached. */ | |
50 LSTREAM_LINE_BUFFERED, | |
51 /* Buffer in standard-size (i.e. 512-byte) blocks. */ | |
52 LSTREAM_BLOCK_BUFFERED, | |
53 /* Buffer in blocks of a specified size. */ | |
54 LSTREAM_BLOCKN_BUFFERED, | |
55 /* Buffer until the stream is closed (only applies to write-only | |
56 streams). Only one call to the stream writer will be made, | |
57 and that is when the stream is closed. */ | |
58 LSTREAM_UNLIMITED | |
59 } Lstream_buffering; | |
60 | |
61 /* Methods defining how this stream works. Some may be undefined. */ | |
62 | |
63 /* We do not implement the seek/tell paradigm. I tried to do that, | |
64 but getting the semantics right in the presence of buffering is | |
65 extremely tricky and very error-prone and basically not worth it. | |
66 This is especially the case with complicated streams like | |
67 decoding streams -- the seek pointer in this case can't be a single | |
68 integer but has to be a whole complicated structure that records | |
69 all of the stream's state at the time. | |
70 | |
71 Rewind semantics are generally easy to implement, so we do provide | |
72 a rewind method. Even rewind() may not be available on a stream, | |
73 however -- e.g. on process output. */ | |
74 | |
75 typedef struct lstream_implementation | |
76 { | |
77 CONST char *name; | |
78 int size; /* Number of additional bytes to be allocated with this | |
79 stream. Access this data using Lstream_data(). */ | |
80 /* Read some data from the stream's end and store it into DATA, which | |
81 can hold SIZE bytes. Return the number of bytes read. A return | |
82 value of 0 means no bytes can be read at this time. This may | |
83 be because of an EOF, or because there is a granularity greater | |
84 than one byte that the stream imposes on the returned data, and | |
85 SIZE is less than this granularity. (This will happen frequently | |
86 for streams that need to return whole characters, because | |
87 Lstream_read() calls the reader function repeatedly until it | |
88 has the number of bytes it wants or until 0 is returned.) | |
89 The lstream functions do not treat a 0 return as EOF or do | |
90 anything special; however, the calling function will interpret | |
91 any 0 it gets back as EOF. This will normally not happen unless | |
92 the caller calls Lstream_read() with a very small size. | |
93 | |
94 This function can be NULL if the stream is output-only. */ | |
95 /* The omniscient mly, blinded by the irresistable thrall of Common | |
96 Lisp, thinks that it is bogus that the types and implementations | |
97 of input and output streams are the same. */ | |
98 int (*reader) (Lstream *stream, unsigned char *data, int size); | |
99 /* Send some data to the stream's end. Data to be sent is in DATA | |
100 and is SIZE bytes. Return the number of bytes sent. This | |
101 function can send and return fewer bytes than is passed in; in | |
102 that case, the function will just be called again until there is | |
103 no data left or 0 is returned. A return value of 0 means that no | |
104 more data can be currently stored, but there is no error; the | |
105 data will be squirrelled away until the writer can accept | |
106 data. (This is useful, e.g., of you're dealing with a | |
107 non-blocking file descriptor and are getting EWOULDBLOCK errors.) | |
108 This function can be NULL if the stream is input-only. */ | |
109 int (*writer) (Lstream *stream, CONST unsigned char *data, int size); | |
110 /* Rewind the stream. If this is NULL, the stream is not seekable. */ | |
111 int (*rewinder) (Lstream *stream); | |
112 /* Indicate whether this stream is seekable -- i.e. it can be rewound. | |
113 This method is ignored if the stream does not have a rewind | |
114 method. If this method is not present, the result is determined | |
115 by whether a rewind method is present. */ | |
116 int (*seekable_p) (Lstream *stream); | |
117 /* Perform any additional operations necessary to flush the | |
118 data in this stream. */ | |
119 int (*flusher) (Lstream *stream); | |
120 /* Perform any additional operations necessary to close this | |
121 stream down. May be NULL. This function is called when | |
122 Lstream_close() is called or when the stream is garbage- | |
123 collected. When this function is called, all pending data | |
124 in the stream will already have been written out. */ | |
125 int (*closer) (Lstream *stream); | |
126 /* Mark this object for garbage collection. Same semantics as | |
127 a standard Lisp_Object marker. This function can be NULL. */ | |
128 Lisp_Object (*marker) (Lisp_Object lstream, void (*markfun) (Lisp_Object)); | |
129 } Lstream_implementation; | |
130 | |
131 #define DEFINE_LSTREAM_IMPLEMENTATION(name,c_name,size) \ | |
132 Lstream_implementation c_name[1] = \ | |
133 { { (name), (size) } } | |
134 | |
135 #define LSTREAM_FL_IS_OPEN 1 | |
136 #define LSTREAM_FL_READ 2 | |
137 #define LSTREAM_FL_WRITE 4 | |
138 #define LSTREAM_FL_NO_PARTIAL_CHARS 8 | |
139 | |
140 struct lstream | |
141 { | |
142 struct lcrecord_header header; | |
143 CONST Lstream_implementation *imp; /* methods for this stream */ | |
144 Lstream_buffering buffering; /* type of buffering in use */ | |
145 int buffering_size; /* number of bytes buffered */ | |
146 | |
147 unsigned char *in_buffer; /* holds characters read from stream end */ | |
148 int in_buffer_size; /* allocated size of buffer */ | |
149 int in_buffer_current; /* number of characters in buffer */ | |
150 int in_buffer_ind; /* pointer to next character to take from buffer */ | |
151 | |
152 unsigned char *out_buffer; /* holds characters to write to stream end */ | |
153 int out_buffer_size; /* allocated size of buffer */ | |
154 int out_buffer_ind; /* pointer to next buffer spot to write a character */ | |
155 | |
156 /* The unget buffer is more or less a stack -- things get pushed | |
157 onto the end and read back from the end. Lstream_read() | |
158 basically reads backwards from the end to get stuff; Lstream_unread() | |
159 similarly has to push the data on backwards. */ | |
160 unsigned char *unget_buffer; /* holds characters pushed back onto input */ | |
161 int unget_buffer_size; /* allocated size of buffer */ | |
162 int unget_buffer_ind; /* pointer to next buffer spot to write a character */ | |
163 | |
164 int byte_count; | |
165 long flags; /* Align pointer for 64 bit machines (kny) */ | |
166 char data[1]; | |
167 }; | |
168 | |
169 #define LSTREAM_TYPE_P(lstr, type) \ | |
170 ((lstr)->imp == lstream_##type) | |
171 | |
172 #ifdef ERROR_CHECK_TYPECHECK | |
173 MAC_DECLARE_EXTERN (struct lstream *, MTlstream_data) | |
174 # define LSTREAM_TYPE_DATA(lstr, type) \ | |
175 MAC_BEGIN \ | |
176 MAC_DECLARE (struct lstream *, MTlstream_data, lstr) \ | |
177 assert (LSTREAM_TYPE_P (MTlstream_data, type)) \ | |
178 MAC_SEP \ | |
179 (struct type##_stream *) Lstream_data (MTlstream_data) \ | |
180 MAC_END | |
181 #else | |
182 # define LSTREAM_TYPE_DATA(lstr, type) \ | |
183 ((struct type##_stream *) Lstream_data (lstr)) | |
184 #endif | |
185 | |
186 /* Declare that lstream-type TYPE has method M; used in | |
187 initialization routines */ | |
188 #define LSTREAM_HAS_METHOD(type, m) \ | |
189 (lstream_##type->m = type##_##m) | |
190 | |
191 | |
192 Lstream *Lstream_new (CONST Lstream_implementation *imp, | |
193 CONST char *mode); | |
194 void Lstream_reopen (Lstream *lstr); | |
195 void Lstream_set_buffering (Lstream *lstr, Lstream_buffering buffering, | |
196 int buffering_size); | |
197 int Lstream_flush (Lstream *lstr); | |
198 int Lstream_flush_out (Lstream *lstr); | |
199 int Lstream_fputc (Lstream *lstr, int c); | |
200 int Lstream_fgetc (Lstream *lstr); | |
201 void Lstream_fungetc (Lstream *lstr, int c); | |
202 int Lstream_read (Lstream *lstr, void *data, int size); | |
203 int Lstream_write (Lstream *lstr, CONST void *data, int size); | |
204 void Lstream_unread (Lstream *lstr, CONST void *data, int size); | |
205 int Lstream_rewind (Lstream *lstr); | |
206 int Lstream_seekable_p (Lstream *lstr); | |
207 int Lstream_close (Lstream *lstr); | |
208 void Lstream_delete (Lstream *lstr); | |
209 void Lstream_set_character_mode (Lstream *str); | |
210 | |
211 /* Call the function equivalent if the out buffer is full. Otherwise, | |
212 add to the end of the out buffer and, if line buffering is called for | |
213 and the character marks the end of a line, write out the buffer. */ | |
214 | |
215 #define Lstream_putc(stream, c) \ | |
216 ((stream)->out_buffer_ind >= (stream)->out_buffer_size ? \ | |
217 Lstream_fputc (stream, c) : \ | |
218 ((stream)->out_buffer[(stream)->out_buffer_ind++] = \ | |
219 (unsigned char) (c), \ | |
220 (stream)->byte_count++, \ | |
221 (stream)->buffering == LSTREAM_LINE_BUFFERED && \ | |
222 (stream)->out_buffer[(stream)->out_buffer_ind - 1] == '\n' ? \ | |
223 Lstream_flush_out (stream) : 0)) | |
224 | |
225 /* Retrieve from unget buffer if there are any characters there; | |
226 else retrieve from in buffer if there's anything there; | |
227 else call the function equivalent */ | |
228 #define Lstream_getc(stream) \ | |
229 ((stream)->unget_buffer_ind > 0 ? \ | |
230 ((stream)->byte_count++, \ | |
231 (stream)->unget_buffer[--(stream)->unget_buffer_ind]) : \ | |
232 (stream)->in_buffer_ind < (stream)->in_buffer_current ? \ | |
233 ((stream)->byte_count++, \ | |
234 (stream)->in_buffer[(stream)->in_buffer_ind++]) : \ | |
235 Lstream_fgetc (stream)) | |
236 | |
237 /* Add to the end if it won't overflow buffer; otherwise call the | |
238 function equivalent */ | |
239 #define Lstream_ungetc(stream, c) \ | |
240 ((stream)->unget_buffer_ind >= (stream)->unget_buffer_size ? \ | |
241 Lstream_fungetc (stream, c) : \ | |
242 (void) ((stream)->byte_count--, \ | |
243 ((stream)->unget_buffer[(stream)->unget_buffer_ind++] = \ | |
244 (unsigned char) (c)))) | |
245 | |
246 #define Lstream_data(stream) ((void *) ((stream)->data)) | |
247 #define Lstream_byte_count(stream) ((stream)->byte_count) | |
248 | |
249 | |
250 | |
251 /************************************************************************/ | |
252 /* working with an Lstream as a stream of Emchars */ | |
253 /************************************************************************/ | |
254 | |
255 # define Lstream_get_emchar(stream) Lstream_getc (stream) | |
256 # define Lstream_put_emchar(stream, ch) Lstream_putc (stream, ch) | |
257 # define Lstream_unget_emchar(stream, ch) Lstream_ungetc (stream, ch) | |
258 | |
259 | |
260 | |
261 /************************************************************************/ | |
262 /* Lstream implementations */ | |
263 /************************************************************************/ | |
264 | |
265 /* Flags we can pass to the filedesc and stdio streams. */ | |
266 | |
267 /* If set, close the descriptor or FILE * when the stream is closed. */ | |
268 #define LSTR_CLOSING 1 | |
269 | |
270 /* If set, allow quitting out of the actual I/O. */ | |
271 #define LSTR_ALLOW_QUIT 2 | |
272 | |
273 /* If set and filedesc_stream_set_pty_flushing() has been called | |
274 on the stream, do not send more than pty_max_bytes on a single | |
275 line without flushing the data out using the eof_char. */ | |
276 #define LSTR_PTY_FLUSHING 4 | |
277 | |
278 /* If set, an EWOULDBLOCK error is not treated as an error but | |
279 simply causes the write function to return 0 as the number | |
280 of bytes written out. */ | |
281 #define LSTR_BLOCKED_OK 8 | |
282 | |
283 Lisp_Object make_stdio_input_stream (FILE *stream, int flags); | |
284 Lisp_Object make_stdio_output_stream (FILE *stream, int flags); | |
285 Lisp_Object make_filedesc_input_stream (int filedesc, int offset, int count, | |
286 int flags); | |
287 Lisp_Object make_filedesc_output_stream (int filedesc, int offset, int count, | |
288 int flags); | |
289 void filedesc_stream_set_pty_flushing (Lstream *stream, | |
290 int pty_max_bytes, | |
291 Bufbyte eof_char); | |
292 int filedesc_stream_was_blocked (Lstream *stream); | |
293 Lisp_Object make_lisp_string_input_stream (Lisp_Object string, | |
294 Bytecount offset, | |
295 Bytecount len); | |
296 Lisp_Object make_fixed_buffer_input_stream (CONST unsigned char *buf, | |
297 int size); | |
298 Lisp_Object make_fixed_buffer_output_stream (unsigned char *buf, | |
299 int size); | |
300 CONST unsigned char *fixed_buffer_input_stream_ptr (Lstream *stream); | |
301 unsigned char *fixed_buffer_output_stream_ptr (Lstream *stream); | |
302 Lisp_Object make_resizing_buffer_output_stream (void); | |
303 unsigned char *resizing_buffer_stream_ptr (Lstream *stream); | |
304 Lisp_Object make_dynarr_output_stream (unsigned_char_dynarr *dyn); | |
305 #define LSTR_SELECTIVE 1 | |
306 #define LSTR_IGNORE_ACCESSIBLE 2 | |
307 Lisp_Object make_lisp_buffer_input_stream (struct buffer *buf, Bufpos start, | |
308 Bufpos end, int flags); | |
309 Lisp_Object make_lisp_buffer_output_stream (struct buffer *buf, Bufpos pos, | |
310 int flags); | |
311 Bufpos lisp_buffer_stream_startpos (Lstream *stream); | |
312 | |
313 #endif /* _XEMACS_LSTREAM_H_ */ |