Mercurial > hg > xemacs-beta
comparison src/lstream.h @ 771:943eaba38521
[xemacs-hg @ 2002-03-13 08:51:24 by ben]
The big ben-mule-21-5 check-in!
Various files were added and deleted. See CHANGES-ben-mule.
There are still some test suite failures. No crashes, though.
Many of the failures have to do with problems in the test suite itself
rather than in the actual code. I'll be addressing these in the next
day or so -- none of the test suite failures are at all critical.
Meanwhile I'll be trying to address the biggest issues -- i.e. build
or run failures, which will almost certainly happen on various platforms.
All comments should be sent to ben@xemacs.org -- use a Cc: if necessary
when sending to mailing lists. There will be pre- and post- tags,
something like
pre-ben-mule-21-5-merge-in, and
post-ben-mule-21-5-merge-in.
author | ben |
---|---|
date | Wed, 13 Mar 2002 08:54:06 +0000 |
parents | fdefd0186b75 |
children | 026c5bf9c134 |
comparison
equal
deleted
inserted
replaced
770:336a418893b5 | 771:943eaba38521 |
---|---|
1 /* Generic stream implementation -- header file. | 1 /* Generic stream implementation -- header file. |
2 Copyright (C) 1995 Free Software Foundation, Inc. | 2 Copyright (C) 1995 Free Software Foundation, Inc. |
3 Copyright (C) 1996 Ben Wing. | 3 Copyright (C) 1996, 2001 Ben Wing. |
4 | 4 |
5 This file is part of XEmacs. | 5 This file is part of XEmacs. |
6 | 6 |
7 XEmacs is free software; you can redistribute it and/or modify it | 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 | 8 under the terms of the GNU General Public License as published by the |
41 | 41 |
42 #ifndef EOF | 42 #ifndef EOF |
43 #define EOF (-1) | 43 #define EOF (-1) |
44 #endif | 44 #endif |
45 | 45 |
46 /* The have been some arguments over the what the type should be that | 46 /* There have been some arguments over the what the type should be that |
47 specifies a count of bytes in a data block to be written out or read in, | 47 specifies a count of bytes in a data block to be written out or read in, |
48 using Lstream_read(), Lstream_write(), and related functions. | 48 using Lstream_read(), Lstream_write(), and related functions. |
49 Originally it was long, which worked fine; Martin "corrected" these to | 49 Originally it was long, which worked fine; Martin "corrected" these to |
50 size_t and ssize_t on the grounds that this is theoretically cleaner and | 50 size_t and ssize_t on the grounds that this is theoretically cleaner and |
51 is in keeping with the C standards. Unfortunately, this practice is | 51 is in keeping with the C standards. Unfortunately, this practice is |
71 bound to fail in all sorts of horrible ways when a number in the | 71 bound to fail in all sorts of horrible ways when a number in the |
72 upper-half of the size_t range is passed in -- this number is | 72 upper-half of the size_t range is passed in -- this number is |
73 unrepresentable as an ssize_t, so code that checks to see how many | 73 unrepresentable as an ssize_t, so code that checks to see how many |
74 bytes are actually written (which is mandatory if you are dealing | 74 bytes are actually written (which is mandatory if you are dealing |
75 with certain types of devices) will get completely screwed up. | 75 with certain types of devices) will get completely screwed up. |
76 | 76 |
77 --ben | 77 --ben |
78 */ | 78 */ |
79 | |
80 typedef enum lstream_buffering | 79 typedef enum lstream_buffering |
81 { | 80 { |
82 /* No buffering. */ | 81 /* No buffering. */ |
83 LSTREAM_UNBUFFERED, | 82 LSTREAM_UNBUFFERED, |
84 /* Buffer until a '\n' character is reached. */ | 83 /* Buffer until a '\n' character is reached. */ |
90 /* Buffer until the stream is closed (only applies to write-only | 89 /* Buffer until the stream is closed (only applies to write-only |
91 streams). Only one call to the stream writer will be made, | 90 streams). Only one call to the stream writer will be made, |
92 and that is when the stream is closed. */ | 91 and that is when the stream is closed. */ |
93 LSTREAM_UNLIMITED | 92 LSTREAM_UNLIMITED |
94 } Lstream_buffering; | 93 } Lstream_buffering; |
94 | |
95 #if 0 | |
96 | |
97 /* #### not currently implemented; correct EOF handling is quite tricky | |
98 in the presence of various levels of filtering streams, and simply | |
99 interpreting 0 as EOF works fairly well as long as the amount of | |
100 data you're attempting to read is large and you know whether the | |
101 source stream at the end of the chain is a pipe (or other blocking | |
102 source) or not. we really should fix this, though. */ | |
103 | |
104 /* Return values from Lstream_read(). We do NOT use the C lib trick | |
105 of returning 0 to maybe indicate EOF because that is simply too | |
106 random and error-prone. It is quite legitimate for there to be no | |
107 data available but no EOF, even when not in the presence of | |
108 non-blocking I/O. For example, decoding/encoding streams (and in | |
109 general, any type of filtering stream) may only be able to return | |
110 data after a certain amount of data on the other end is | |
111 available. */ | |
112 | |
113 #define LSTREAM_EOF -2 | |
114 | |
115 #endif /* 0 */ | |
116 | |
117 #define LSTREAM_ERROR -1 | |
95 | 118 |
96 /* Methods defining how this stream works. Some may be undefined. */ | 119 /* Methods defining how this stream works. Some may be undefined. */ |
97 | 120 |
98 /* We do not implement the seek/tell paradigm. I tried to do that, | 121 /* We do not implement the seek/tell paradigm. I tried to do that, |
99 but getting the semantics right in the presence of buffering is | 122 but getting the semantics right in the presence of buffering is |
157 by whether a rewind method is present. */ | 180 by whether a rewind method is present. */ |
158 int (*seekable_p) (Lstream *stream); | 181 int (*seekable_p) (Lstream *stream); |
159 /* Perform any additional operations necessary to flush the | 182 /* Perform any additional operations necessary to flush the |
160 data in this stream. */ | 183 data in this stream. */ |
161 int (*flusher) (Lstream *stream); | 184 int (*flusher) (Lstream *stream); |
162 /* Perform any additional operations necessary to close this | 185 /* Perform any additional operations necessary to close this stream down. |
163 stream down. May be NULL. This function is called when | 186 May be NULL. This function is called when Lstream_close() is called |
164 Lstream_close() is called or when the stream is garbage- | 187 (which will be called automatically on any open streams when they are |
165 collected. When this function is called, all pending data | 188 garbage-collected or deleted with Lstream_delete()). When this |
166 in the stream will already have been written out. */ | 189 function is called, all pending data in the stream will already have |
190 been written out; however, the closer write more data, e.g. an "end" | |
191 section at the end of a file. */ | |
167 int (*closer) (Lstream *stream); | 192 int (*closer) (Lstream *stream); |
193 /* Clean up any remaining data at the time that a stream is | |
194 garbage-collected or deleted with Lstream_delete(). If the stream was | |
195 open at this point, the finalizer is called after calling | |
196 Lstream_close(). Called only once (NOT called at disksave time). */ | |
197 void (*finalizer) (Lstream *stream); | |
168 /* Mark this object for garbage collection. Same semantics as | 198 /* Mark this object for garbage collection. Same semantics as |
169 a standard Lisp_Object marker. This function can be NULL. */ | 199 a standard Lisp_Object marker. This function can be NULL. */ |
170 Lisp_Object (*marker) (Lisp_Object lstream); | 200 Lisp_Object (*marker) (Lisp_Object lstream); |
171 } Lstream_implementation; | 201 } Lstream_implementation; |
172 | 202 |
173 #define DEFINE_LSTREAM_IMPLEMENTATION(name,c_name,size) \ | 203 #define DEFINE_LSTREAM_IMPLEMENTATION(name, c_name) \ |
174 Lstream_implementation c_name[1] = \ | 204 Lstream_implementation lstream_##c_name[1] = \ |
175 { { (name), (size) } } | 205 { { (name), sizeof (struct c_name##_stream) } } |
206 | |
207 #define DECLARE_LSTREAM(c_name) \ | |
208 extern Lstream_implementation lstream_##c_name[] | |
176 | 209 |
177 #define LSTREAM_FL_IS_OPEN 1 | 210 #define LSTREAM_FL_IS_OPEN 1 |
178 #define LSTREAM_FL_READ 2 | 211 #define LSTREAM_FL_READ 2 |
179 #define LSTREAM_FL_WRITE 4 | 212 #define LSTREAM_FL_WRITE 4 |
180 #define LSTREAM_FL_NO_PARTIAL_CHARS 8 | 213 #define LSTREAM_FL_NO_PARTIAL_CHARS 8 |
224 const Lstream_implementation *imp) | 257 const Lstream_implementation *imp) |
225 { | 258 { |
226 assert (stream->imp == imp); | 259 assert (stream->imp == imp); |
227 return stream; | 260 return stream; |
228 } | 261 } |
229 # define LSTREAM_TYPE_DATA(lstr, type) \ | 262 # define LSTREAM_TYPE_DATA(lstr, type) \ |
230 ((struct type##_stream *) \ | 263 ((struct type##_stream *) \ |
231 Lstream_data (error_check_lstream_type(lstr, lstream_##type))) | 264 Lstream_data (error_check_lstream_type (lstr, lstream_##type))) |
232 #else | 265 #else |
233 # define LSTREAM_TYPE_DATA(lstr, type) \ | 266 # define LSTREAM_TYPE_DATA(lstr, type) \ |
234 ((struct type##_stream *) Lstream_data (lstr)) | 267 ((struct type##_stream *) Lstream_data (lstr)) |
235 #endif | 268 #endif |
236 | 269 |
237 /* Declare that lstream-type TYPE has method M; used in | 270 /* Declare that lstream-type TYPE has method M; used in initialization |
238 initialization routines */ | 271 routines */ |
239 #define LSTREAM_HAS_METHOD(type, m) \ | 272 #define LSTREAM_HAS_METHOD(type, m) \ |
240 (lstream_##type->m = type##_##m) | 273 (lstream_##type->m = type##_##m) |
241 | 274 |
242 | 275 |
243 Lstream *Lstream_new (const Lstream_implementation *imp, | 276 Lstream *Lstream_new (const Lstream_implementation *imp, |
250 int Lstream_fputc (Lstream *lstr, int c); | 283 int Lstream_fputc (Lstream *lstr, int c); |
251 int Lstream_fgetc (Lstream *lstr); | 284 int Lstream_fgetc (Lstream *lstr); |
252 void Lstream_fungetc (Lstream *lstr, int c); | 285 void Lstream_fungetc (Lstream *lstr, int c); |
253 Bytecount Lstream_read (Lstream *lstr, void *data, | 286 Bytecount Lstream_read (Lstream *lstr, void *data, |
254 Bytecount size); | 287 Bytecount size); |
255 Bytecount Lstream_write (Lstream *lstr, const void *data, | 288 int Lstream_write (Lstream *lstr, const void *data, |
256 Bytecount size); | 289 Bytecount size); |
257 int Lstream_was_blocked_p (Lstream *lstr); | 290 int Lstream_was_blocked_p (Lstream *lstr); |
258 void Lstream_unread (Lstream *lstr, const void *data, Bytecount size); | 291 void Lstream_unread (Lstream *lstr, const void *data, Bytecount size); |
259 int Lstream_rewind (Lstream *lstr); | 292 int Lstream_rewind (Lstream *lstr); |
260 int Lstream_seekable_p (Lstream *lstr); | 293 int Lstream_seekable_p (Lstream *lstr); |
261 int Lstream_close (Lstream *lstr); | 294 int Lstream_close (Lstream *lstr); |
295 | |
262 void Lstream_delete (Lstream *lstr); | 296 void Lstream_delete (Lstream *lstr); |
263 void Lstream_set_character_mode (Lstream *str); | 297 void Lstream_set_character_mode (Lstream *str); |
264 | 298 void Lstream_unset_character_mode (Lstream *lstr); |
265 /* Call the function equivalent if the out buffer is full. Otherwise, | 299 |
266 add to the end of the out buffer and, if line buffering is called for | 300 /* Lstream_putc: Write out one byte to the stream. This is a macro |
267 and the character marks the end of a line, write out the buffer. */ | 301 and so it is very efficient. The C argument is only evaluated once |
268 | 302 but the STREAM argument is evaluated more than once. Returns 0 on |
269 #define Lstream_putc(stream, c) \ | 303 success, -1 on error. */ |
270 ((stream)->out_buffer_ind >= (stream)->out_buffer_size ? \ | 304 |
271 Lstream_fputc (stream, c) : \ | 305 #define Lstream_putc(stream, c) \ |
272 ((stream)->out_buffer[(stream)->out_buffer_ind++] = \ | 306 /* Call the function equivalent if the out buffer is full. Otherwise, \ |
273 (unsigned char) (c), \ | 307 add to the end of the out buffer and, if line buffering is called for \ |
274 (stream)->byte_count++, \ | 308 and the character marks the end of a line, write out the buffer. */ \ |
275 (stream)->buffering == LSTREAM_LINE_BUFFERED && \ | 309 ((stream)->out_buffer_ind >= (stream)->out_buffer_size ? \ |
276 (stream)->out_buffer[(stream)->out_buffer_ind - 1] == '\n' ? \ | 310 Lstream_fputc (stream, c) : \ |
311 ((stream)->out_buffer[(stream)->out_buffer_ind++] = \ | |
312 (unsigned char) (c), \ | |
313 (stream)->byte_count++, \ | |
314 (stream)->buffering == LSTREAM_LINE_BUFFERED && \ | |
315 (stream)->out_buffer[(stream)->out_buffer_ind - 1] == '\n' ? \ | |
277 Lstream_flush_out (stream) : 0)) | 316 Lstream_flush_out (stream) : 0)) |
278 | 317 |
279 /* Retrieve from unget buffer if there are any characters there; | 318 /* Lstream_getc: Read one byte from the stream and returns it as an |
280 else retrieve from in buffer if there's anything there; | 319 unsigned char cast to an int, or EOF on end of file or error. This |
281 else call the function equivalent */ | 320 is a macro and so it is very efficient. The STREAM argument is |
282 #define Lstream_getc(stream) \ | 321 evaluated more than once. */ |
322 | |
323 #define Lstream_getc(stream) \ | |
324 /* Retrieve from unget buffer if there are any characters there; \ | |
325 else retrieve from in buffer if there's anything there; \ | |
326 else call the function equivalent */ \ | |
283 ((stream)->unget_buffer_ind > 0 ? \ | 327 ((stream)->unget_buffer_ind > 0 ? \ |
284 ((stream)->byte_count++, \ | 328 ((stream)->byte_count++, \ |
285 (stream)->unget_buffer[--(stream)->unget_buffer_ind]) : \ | 329 (stream)->unget_buffer[--(stream)->unget_buffer_ind]) : \ |
286 (stream)->in_buffer_ind < (stream)->in_buffer_current ? \ | 330 (stream)->in_buffer_ind < (stream)->in_buffer_current ? \ |
287 ((stream)->byte_count++, \ | 331 ((stream)->byte_count++, \ |
288 (stream)->in_buffer[(stream)->in_buffer_ind++]) : \ | 332 (stream)->in_buffer[(stream)->in_buffer_ind++]) : \ |
289 Lstream_fgetc (stream)) | 333 Lstream_fgetc (stream)) |
290 | 334 |
291 /* Add to the end if it won't overflow buffer; otherwise call the | 335 /* Lstream_ungetc: Push one byte back onto the input queue, cast to |
292 function equivalent */ | 336 unsigned char. This will be the next byte read from the stream. |
337 Any number of bytes can be pushed back and will be read in the | |
338 reverse order they were pushed back -- most recent first. (This is | |
339 necessary for consistency -- if there are a number of bytes that | |
340 have been unread and I read and unread a byte, it needs to be the | |
341 first to be read again.) This is a macro and so it is very | |
342 efficient. The C argument is only evaluated once but the STREAM | |
343 argument is evaluated more than once. | |
344 */ | |
345 | |
293 #define Lstream_ungetc(stream, c) \ | 346 #define Lstream_ungetc(stream, c) \ |
347 /* Add to the end if it won't overflow buffer; otherwise call the \ | |
348 function equivalent */ \ | |
294 ((stream)->unget_buffer_ind >= (stream)->unget_buffer_size ? \ | 349 ((stream)->unget_buffer_ind >= (stream)->unget_buffer_size ? \ |
295 Lstream_fungetc (stream, c) : \ | 350 Lstream_fungetc (stream, c) : \ |
296 (void) ((stream)->byte_count--, \ | 351 (void) ((stream)->byte_count--, \ |
297 ((stream)->unget_buffer[(stream)->unget_buffer_ind++] = \ | 352 ((stream)->unget_buffer[(stream)->unget_buffer_ind++] = \ |
298 (unsigned char) (c)))) | 353 (unsigned char) (c)))) |
305 /* working with an Lstream as a stream of Emchars */ | 360 /* working with an Lstream as a stream of Emchars */ |
306 /************************************************************************/ | 361 /************************************************************************/ |
307 | 362 |
308 #ifdef MULE | 363 #ifdef MULE |
309 | 364 |
310 #ifndef BYTE_ASCII_P | |
311 #include "mule-charset.h" | |
312 #endif | |
313 | |
314 INLINE_HEADER Emchar Lstream_get_emchar (Lstream *stream); | 365 INLINE_HEADER Emchar Lstream_get_emchar (Lstream *stream); |
315 INLINE_HEADER Emchar | 366 INLINE_HEADER Emchar |
316 Lstream_get_emchar (Lstream *stream) | 367 Lstream_get_emchar (Lstream *stream) |
317 { | 368 { |
318 int c = Lstream_getc (stream); | 369 int c = Lstream_getc (stream); |
319 return (c < 0x80 /* c == EOF || BYTE_ASCII_P (c) */ | 370 return (c < 0x80 /* c == EOF || BYTE_ASCII_P (c) */ |
320 ? (Emchar) c | 371 ? (Emchar) c |
321 : Lstream_get_emchar_1 (stream, c)); | 372 : Lstream_get_emchar_1 (stream, c)); |
322 } | 373 } |
374 | |
375 /* Write an Emchar to a stream. Return value is 0 for success, -1 for | |
376 failure. */ | |
323 | 377 |
324 INLINE_HEADER int Lstream_put_emchar (Lstream *stream, Emchar ch); | 378 INLINE_HEADER int Lstream_put_emchar (Lstream *stream, Emchar ch); |
325 INLINE_HEADER int | 379 INLINE_HEADER int |
326 Lstream_put_emchar (Lstream *stream, Emchar ch) | 380 Lstream_put_emchar (Lstream *stream, Emchar ch) |
327 { | 381 { |