comparison src/lstream.c @ 442:abe6d1db359e r21-2-36

Import from CVS: tag r21-2-36
author cvs
date Mon, 13 Aug 2007 11:35:02 +0200
parents 8de8e3f6228a
children 576fb035e263
comparison
equal deleted inserted replaced
441:72a7cfa4a488 442:abe6d1db359e
24 24
25 /* Written by Ben Wing. */ 25 /* Written by Ben Wing. */
26 26
27 #include <config.h> 27 #include <config.h>
28 #include "lisp.h" 28 #include "lisp.h"
29 #include <limits.h>
30 29
31 #include "buffer.h" 30 #include "buffer.h"
32 #include "insdel.h" 31 #include "insdel.h"
33 #include "lstream.h" 32 #include "lstream.h"
34 33
50 in C. The reason for this is that "stream" is too generic a name 49 in C. The reason for this is that "stream" is too generic a name
51 for C; too much likelihood of conflict/confusion with C++, etc. */ 50 for C; too much likelihood of conflict/confusion with C++, etc. */
52 51
53 /* Functions are as follows: 52 /* Functions are as follows:
54 53
55 Lstream *Lstream_new (Lstream_implementation *imp, CONST char *mode) 54 Lstream *Lstream_new (Lstream_implementation *imp, const char *mode)
56 Allocate and return a new Lstream. This function is not 55 Allocate and return a new Lstream. This function is not
57 really meant to be called directly; rather, each stream type 56 really meant to be called directly; rather, each stream type
58 should provide its own stream creation function, which 57 should provide its own stream creation function, which
59 creates the stream and does any other necessary creation 58 creates the stream and does any other necessary creation
60 stuff (e.g. opening a file). 59 stuff (e.g. opening a file).
178 Lstream_close (lstr); 177 Lstream_close (lstr);
179 } 178 }
180 } 179 }
181 180
182 static size_t 181 static size_t
183 sizeof_lstream (CONST void *header) 182 sizeof_lstream (const void *header)
184 { 183 {
185 CONST Lstream *lstr = (CONST Lstream *) header; 184 const Lstream *lstr = (const Lstream *) header;
186 return sizeof (*lstr) + lstr->imp->size - 1; 185 return sizeof (*lstr) + lstr->imp->size - 1;
187 } 186 }
188 187
189 DEFINE_LRECORD_SEQUENCE_IMPLEMENTATION ("stream", lstream, 188 DEFINE_LRECORD_SEQUENCE_IMPLEMENTATION ("stream", lstream,
190 mark_lstream, print_lstream, 189 mark_lstream, print_lstream,
208 case LSTREAM_UNLIMITED: 207 case LSTREAM_UNLIMITED:
209 lstr->buffering_size = INT_MAX; break; 208 lstr->buffering_size = INT_MAX; break;
210 } 209 }
211 } 210 }
212 211
213 static CONST Lstream_implementation *lstream_types[32]; 212 static const Lstream_implementation *lstream_types[32];
214 static Lisp_Object Vlstream_free_list[32]; 213 static Lisp_Object Vlstream_free_list[32];
215 static int lstream_type_count; 214 static int lstream_type_count;
216 215
217 Lstream * 216 Lstream *
218 Lstream_new (CONST Lstream_implementation *imp, CONST char *mode) 217 Lstream_new (const Lstream_implementation *imp, const char *mode)
219 { 218 {
220 Lstream *p; 219 Lstream *p;
221 int i; 220 int i;
222 221
223 for (i = 0; i < lstream_type_count; i++) 222 for (i = 0; i < lstream_type_count; i++)
280 } 279 }
281 280
282 #define Lstream_internal_error(reason, lstr) \ 281 #define Lstream_internal_error(reason, lstr) \
283 Lstream_signal_simple_error ("Internal error: " reason, lstr) 282 Lstream_signal_simple_error ("Internal error: " reason, lstr)
284 283
285 static void Lstream_signal_simple_error (CONST char *reason, Lstream *lstr) 284 static void Lstream_signal_simple_error (const char *reason, Lstream *lstr)
286 { 285 {
287 Lisp_Object obj; 286 Lisp_Object obj;
288 XSETLSTREAM (obj, lstr); 287 XSETLSTREAM (obj, lstr);
289 signal_simple_error (reason, obj); 288 signal_simple_error (reason, obj);
290 } 289 }
317 if (lstr->flags & LSTREAM_FL_NO_PARTIAL_CHARS) 316 if (lstr->flags & LSTREAM_FL_NO_PARTIAL_CHARS)
318 /* It's quite possible for us to get passed an incomplete 317 /* It's quite possible for us to get passed an incomplete
319 character at the end. We need to spit back that 318 character at the end. We need to spit back that
320 incomplete character. */ 319 incomplete character. */
321 { 320 {
322 CONST unsigned char *data = lstr->out_buffer; 321 const unsigned char *data = lstr->out_buffer;
323 CONST unsigned char *dataend = data + size - 1; 322 const unsigned char *dataend = data + size - 1;
324 assert (size > 0); /* safety check ... */ 323 assert (size > 0); /* safety check ... */
325 /* Optimize the most common case. */ 324 /* Optimize the most common case. */
326 if (!BYTE_ASCII_P (*dataend)) 325 if (!BYTE_ASCII_P (*dataend))
327 { 326 {
328 /* Go back to the beginning of the last (and possibly partial) 327 /* Go back to the beginning of the last (and possibly partial)
413 } 412 }
414 413
415 /* Like Lstream_write(), but does not handle line-buffering correctly. */ 414 /* Like Lstream_write(), but does not handle line-buffering correctly. */
416 415
417 static ssize_t 416 static ssize_t
418 Lstream_write_1 (Lstream *lstr, CONST void *data, size_t size) 417 Lstream_write_1 (Lstream *lstr, const void *data, size_t size)
419 { 418 {
420 CONST unsigned char *p = (CONST unsigned char *) data; 419 const unsigned char *p = (const unsigned char *) data;
421 ssize_t off = 0; 420 ssize_t off = 0;
422 if (! (lstr->flags & LSTREAM_FL_IS_OPEN)) 421 if (! (lstr->flags & LSTREAM_FL_IS_OPEN))
423 Lstream_internal_error ("lstream not open", lstr); 422 Lstream_internal_error ("lstream not open", lstr);
424 if (! (lstr->flags & LSTREAM_FL_WRITE)) 423 if (! (lstr->flags & LSTREAM_FL_WRITE))
425 Lstream_internal_error ("lstream not open for writing", lstr); 424 Lstream_internal_error ("lstream not open for writing", lstr);
473 Lstream_write_1(), which writes in chunks. Otherwise, we 472 Lstream_write_1(), which writes in chunks. Otherwise, we
474 repeatedly call Lstream_putc(), which knows how to handle 473 repeatedly call Lstream_putc(), which knows how to handle
475 line buffering. Returns number of bytes written. */ 474 line buffering. Returns number of bytes written. */
476 475
477 ssize_t 476 ssize_t
478 Lstream_write (Lstream *lstr, CONST void *data, size_t size) 477 Lstream_write (Lstream *lstr, const void *data, size_t size)
479 { 478 {
480 size_t i; 479 size_t i;
481 CONST unsigned char *p = (CONST unsigned char *) data; 480 const unsigned char *p = (const unsigned char *) data;
482 481
483 if (size == 0) 482 if (size == 0)
484 return size; 483 return size;
485 if (lstr->buffering != LSTREAM_LINE_BUFFERED) 484 if (lstr->buffering != LSTREAM_LINE_BUFFERED)
486 return Lstream_write_1 (lstr, data, size); 485 return Lstream_write_1 (lstr, data, size);
582 if ((lstr->flags & LSTREAM_FL_NO_PARTIAL_CHARS) && off > 0) 581 if ((lstr->flags & LSTREAM_FL_NO_PARTIAL_CHARS) && off > 0)
583 { 582 {
584 /* It's quite possible for us to get passed an incomplete 583 /* It's quite possible for us to get passed an incomplete
585 character at the end. We need to spit back that 584 character at the end. We need to spit back that
586 incomplete character. */ 585 incomplete character. */
587 CONST unsigned char *dataend = p + off - 1; 586 const unsigned char *dataend = p + off - 1;
588 /* Optimize the most common case. */ 587 /* Optimize the most common case. */
589 if (!BYTE_ASCII_P (*dataend)) 588 if (!BYTE_ASCII_P (*dataend))
590 { 589 {
591 /* Go back to the beginning of the last (and possibly partial) 590 /* Go back to the beginning of the last (and possibly partial)
592 character, and bump forward to see if the character is 591 character, and bump forward to see if the character is
605 604
606 return off == 0 && error_occurred ? -1 : (ssize_t) off; 605 return off == 0 && error_occurred ? -1 : (ssize_t) off;
607 } 606 }
608 607
609 void 608 void
610 Lstream_unread (Lstream *lstr, CONST void *data, size_t size) 609 Lstream_unread (Lstream *lstr, const void *data, size_t size)
611 { 610 {
612 CONST unsigned char *p = (CONST unsigned char *) data; 611 const unsigned char *p = (const unsigned char *) data;
613 612
614 /* Make sure buffer is big enough */ 613 /* Make sure buffer is big enough */
615 DO_REALLOC (lstr->unget_buffer, lstr->unget_buffer_size, 614 DO_REALLOC (lstr->unget_buffer, lstr->unget_buffer_size,
616 lstr->unget_buffer_ind + size, unsigned char); 615 lstr->unget_buffer_ind + size, unsigned char);
617 616
763 762
764 DEFINE_LSTREAM_IMPLEMENTATION ("stdio", lstream_stdio, 763 DEFINE_LSTREAM_IMPLEMENTATION ("stdio", lstream_stdio,
765 sizeof (struct stdio_stream)); 764 sizeof (struct stdio_stream));
766 765
767 static Lisp_Object 766 static Lisp_Object
768 make_stdio_stream_1 (FILE *stream, int flags, CONST char *mode) 767 make_stdio_stream_1 (FILE *stream, int flags, const char *mode)
769 { 768 {
770 Lisp_Object obj; 769 Lisp_Object obj;
771 Lstream *lstr = Lstream_new (lstream_stdio, mode); 770 Lstream *lstr = Lstream_new (lstream_stdio, mode);
772 struct stdio_stream *str = STDIO_STREAM_DATA (lstr); 771 struct stdio_stream *str = STDIO_STREAM_DATA (lstr);
773 str->file = stream; 772 str->file = stream;
816 return -1; 815 return -1;
817 return val; 816 return val;
818 } 817 }
819 818
820 static ssize_t 819 static ssize_t
821 stdio_writer (Lstream *stream, CONST unsigned char *data, size_t size) 820 stdio_writer (Lstream *stream, const unsigned char *data, size_t size)
822 { 821 {
823 struct stdio_stream *str = STDIO_STREAM_DATA (stream); 822 struct stdio_stream *str = STDIO_STREAM_DATA (stream);
824 size_t val = fwrite (data, 1, size, str->file); 823 size_t val = fwrite (data, 1, size, str->file);
825 if (!val && ferror (str->file)) 824 if (!val && ferror (str->file))
826 return -1; 825 return -1;
895 OFFSET is the offset from the *current* file pointer that the reading 894 OFFSET is the offset from the *current* file pointer that the reading
896 should start at. COUNT is the number of bytes to be read (it is 895 should start at. COUNT is the number of bytes to be read (it is
897 ignored when writing); -1 for unlimited. */ 896 ignored when writing); -1 for unlimited. */
898 static Lisp_Object 897 static Lisp_Object
899 make_filedesc_stream_1 (int filedesc, int offset, int count, int flags, 898 make_filedesc_stream_1 (int filedesc, int offset, int count, int flags,
900 CONST char *mode) 899 const char *mode)
901 { 900 {
902 Lisp_Object obj; 901 Lisp_Object obj;
903 Lstream *lstr = Lstream_new (lstream_filedesc, mode); 902 Lstream *lstr = Lstream_new (lstream_filedesc, mode);
904 struct filedesc_stream *fstr = FILEDESC_STREAM_DATA (lstr); 903 struct filedesc_stream *fstr = FILEDESC_STREAM_DATA (lstr);
905 fstr->fd = filedesc; 904 fstr->fd = filedesc;
960 #endif 959 #endif
961 return 0; 960 return 0;
962 } 961 }
963 962
964 static ssize_t 963 static ssize_t
965 filedesc_writer (Lstream *stream, CONST unsigned char *data, size_t size) 964 filedesc_writer (Lstream *stream, const unsigned char *data, size_t size)
966 { 965 {
967 struct filedesc_stream *str = FILEDESC_STREAM_DATA (stream); 966 struct filedesc_stream *str = FILEDESC_STREAM_DATA (stream);
968 ssize_t retval; 967 ssize_t retval;
969 int need_newline = 0; 968 int need_newline = 0;
970 969
975 Maybe all the PTY crap here should be moved into another stream 974 Maybe all the PTY crap here should be moved into another stream
976 that does nothing but periodically insert EOF's as necessary. */ 975 that does nothing but periodically insert EOF's as necessary. */
977 if (str->pty_flushing) 976 if (str->pty_flushing)
978 { 977 {
979 /* To make life easy, only send out one line at the most. */ 978 /* To make life easy, only send out one line at the most. */
980 CONST unsigned char *ptr; 979 const unsigned char *ptr;
981 980
982 ptr = (CONST unsigned char *) memchr (data, '\n', size); 981 ptr = (const unsigned char *) memchr (data, '\n', size);
983 if (ptr) 982 if (ptr)
984 need_newline = 1; 983 need_newline = 1;
985 else 984 else
986 ptr = data + size; 985 ptr = data + size;
987 if (ptr - data >= str->pty_max_bytes - str->chars_sans_newline) 986 if (ptr - data >= str->pty_max_bytes - str->chars_sans_newline)
1243 #define FIXED_BUFFER_STREAM_DATA(stream) \ 1242 #define FIXED_BUFFER_STREAM_DATA(stream) \
1244 LSTREAM_TYPE_DATA (stream, fixed_buffer) 1243 LSTREAM_TYPE_DATA (stream, fixed_buffer)
1245 1244
1246 struct fixed_buffer_stream 1245 struct fixed_buffer_stream
1247 { 1246 {
1248 CONST unsigned char *inbuf; 1247 const unsigned char *inbuf;
1249 unsigned char *outbuf; 1248 unsigned char *outbuf;
1250 size_t size; 1249 size_t size;
1251 size_t offset; 1250 size_t offset;
1252 }; 1251 };
1253 1252
1254 DEFINE_LSTREAM_IMPLEMENTATION ("fixed-buffer", lstream_fixed_buffer, 1253 DEFINE_LSTREAM_IMPLEMENTATION ("fixed-buffer", lstream_fixed_buffer,
1255 sizeof (struct fixed_buffer_stream)); 1254 sizeof (struct fixed_buffer_stream));
1256 1255
1257 Lisp_Object 1256 Lisp_Object
1258 make_fixed_buffer_input_stream (CONST void *buf, size_t size) 1257 make_fixed_buffer_input_stream (const void *buf, size_t size)
1259 { 1258 {
1260 Lisp_Object obj; 1259 Lisp_Object obj;
1261 Lstream *lstr = Lstream_new (lstream_fixed_buffer, "r"); 1260 Lstream *lstr = Lstream_new (lstream_fixed_buffer, "r");
1262 struct fixed_buffer_stream *str = FIXED_BUFFER_STREAM_DATA (lstr); 1261 struct fixed_buffer_stream *str = FIXED_BUFFER_STREAM_DATA (lstr);
1263 str->inbuf = (const unsigned char *) buf; 1262 str->inbuf = (const unsigned char *) buf;
1287 str->offset += size; 1286 str->offset += size;
1288 return size; 1287 return size;
1289 } 1288 }
1290 1289
1291 static ssize_t 1290 static ssize_t
1292 fixed_buffer_writer (Lstream *stream, CONST unsigned char *data, size_t size) 1291 fixed_buffer_writer (Lstream *stream, const unsigned char *data, size_t size)
1293 { 1292 {
1294 struct fixed_buffer_stream *str = FIXED_BUFFER_STREAM_DATA (stream); 1293 struct fixed_buffer_stream *str = FIXED_BUFFER_STREAM_DATA (stream);
1295 if (str->offset == str->size) 1294 if (str->offset == str->size)
1296 { 1295 {
1297 /* If we're at the end, just throw away the data and pretend 1296 /* If we're at the end, just throw away the data and pretend
1310 { 1309 {
1311 FIXED_BUFFER_STREAM_DATA (stream)->offset = 0; 1310 FIXED_BUFFER_STREAM_DATA (stream)->offset = 0;
1312 return 0; 1311 return 0;
1313 } 1312 }
1314 1313
1315 CONST unsigned char * 1314 const unsigned char *
1316 fixed_buffer_input_stream_ptr (Lstream *stream) 1315 fixed_buffer_input_stream_ptr (Lstream *stream)
1317 { 1316 {
1318 assert (stream->imp == lstream_fixed_buffer); 1317 assert (stream->imp == lstream_fixed_buffer);
1319 return FIXED_BUFFER_STREAM_DATA (stream)->inbuf; 1318 return FIXED_BUFFER_STREAM_DATA (stream)->inbuf;
1320 } 1319 }
1349 XSETLSTREAM (obj, Lstream_new (lstream_resizing_buffer, "w")); 1348 XSETLSTREAM (obj, Lstream_new (lstream_resizing_buffer, "w"));
1350 return obj; 1349 return obj;
1351 } 1350 }
1352 1351
1353 static ssize_t 1352 static ssize_t
1354 resizing_buffer_writer (Lstream *stream, CONST unsigned char *data, size_t size) 1353 resizing_buffer_writer (Lstream *stream, const unsigned char *data, size_t size)
1355 { 1354 {
1356 struct resizing_buffer_stream *str = RESIZING_BUFFER_STREAM_DATA (stream); 1355 struct resizing_buffer_stream *str = RESIZING_BUFFER_STREAM_DATA (stream);
1357 DO_REALLOC (str->buf, str->allocked, str->stored + size, unsigned char); 1356 DO_REALLOC (str->buf, str->allocked, str->stored + size, unsigned char);
1358 memcpy (str->buf + str->stored, data, size); 1357 memcpy (str->buf + str->stored, data, size);
1359 str->stored += size; 1358 str->stored += size;
1411 DYNARR_STREAM_DATA (XLSTREAM (obj))->dyn = dyn; 1410 DYNARR_STREAM_DATA (XLSTREAM (obj))->dyn = dyn;
1412 return obj; 1411 return obj;
1413 } 1412 }
1414 1413
1415 static ssize_t 1414 static ssize_t
1416 dynarr_writer (Lstream *stream, CONST unsigned char *data, size_t size) 1415 dynarr_writer (Lstream *stream, const unsigned char *data, size_t size)
1417 { 1416 {
1418 struct dynarr_stream *str = DYNARR_STREAM_DATA (stream); 1417 struct dynarr_stream *str = DYNARR_STREAM_DATA (stream);
1419 Dynarr_add_many (str->dyn, data, size); 1418 Dynarr_add_many (str->dyn, data, size);
1420 return size; 1419 return size;
1421 } 1420 }
1454 DEFINE_LSTREAM_IMPLEMENTATION ("lisp-buffer", lstream_lisp_buffer, 1453 DEFINE_LSTREAM_IMPLEMENTATION ("lisp-buffer", lstream_lisp_buffer,
1455 sizeof (struct lisp_buffer_stream)); 1454 sizeof (struct lisp_buffer_stream));
1456 1455
1457 static Lisp_Object 1456 static Lisp_Object
1458 make_lisp_buffer_stream_1 (struct buffer *buf, Bufpos start, Bufpos end, 1457 make_lisp_buffer_stream_1 (struct buffer *buf, Bufpos start, Bufpos end,
1459 int flags, CONST char *mode) 1458 int flags, const char *mode)
1460 { 1459 {
1461 Lisp_Object obj; 1460 Lisp_Object obj;
1462 Lstream *lstr; 1461 Lstream *lstr;
1463 struct lisp_buffer_stream *str; 1462 struct lisp_buffer_stream *str;
1464 Bufpos bmin, bmax; 1463 Bufpos bmin, bmax;
1593 set_bi_marker_position (str->start, end); 1592 set_bi_marker_position (str->start, end);
1594 return data - orig_data; 1593 return data - orig_data;
1595 } 1594 }
1596 1595
1597 static ssize_t 1596 static ssize_t
1598 lisp_buffer_writer (Lstream *stream, CONST unsigned char *data, size_t size) 1597 lisp_buffer_writer (Lstream *stream, const unsigned char *data, size_t size)
1599 { 1598 {
1600 struct lisp_buffer_stream *str = LISP_BUFFER_STREAM_DATA (stream); 1599 struct lisp_buffer_stream *str = LISP_BUFFER_STREAM_DATA (stream);
1601 Bufpos pos; 1600 Bufpos pos;
1602 struct buffer *buf = XBUFFER (str->buffer); 1601 struct buffer *buf = XBUFFER (str->buffer);
1603 1602
1703 } 1702 }
1704 1703
1705 void 1704 void
1706 vars_of_lstream (void) 1705 vars_of_lstream (void)
1707 { 1706 {
1707 INIT_LRECORD_IMPLEMENTATION (lstream);
1708
1708 reinit_vars_of_lstream (); 1709 reinit_vars_of_lstream ();
1709 } 1710 }