428
+ − 1 /* Generic stream implementation.
+ − 2 Copyright (C) 1995 Free Software Foundation, Inc.
+ − 3 Copyright (C) 1995 Sun Microsystems, Inc.
788
+ − 4 Copyright (C) 1996, 2001, 2002 Ben Wing.
428
+ − 5
+ − 6 This file is part of XEmacs.
+ − 7
+ − 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
+ − 11 later version.
+ − 12
+ − 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
+ − 16 for more details.
+ − 17
+ − 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. */
+ − 22
+ − 23 /* Synched up with: Not in FSF. */
+ − 24
+ − 25 /* Written by Ben Wing. */
+ − 26
+ − 27 #include <config.h>
+ − 28 #include "lisp.h"
+ − 29
+ − 30 #include "buffer.h"
+ − 31 #include "insdel.h"
+ − 32 #include "lstream.h"
+ − 33
+ − 34 #include "sysfile.h"
+ − 35
771
+ − 36 /* This module provides a generic buffering stream implementation.
428
+ − 37 Conceptually, you send data to the stream or read data from the
+ − 38 stream, not caring what's on the other end of the stream. The
+ − 39 other end could be another stream, a file descriptor, a stdio
+ − 40 stream, a fixed block of memory, a reallocating block of memory,
+ − 41 etc. The main purpose of the stream is to provide a standard
+ − 42 interface and to do buffering. Macros are defined to read
+ − 43 or write characters, so the calling functions do not have to
+ − 44 worry about blocking data together in order to achieve efficiency.
+ − 45
771
+ − 46 Note that this object is called "stream" in Lisp but "lstream"
428
+ − 47 in C. The reason for this is that "stream" is too generic a name
+ − 48 for C; too much likelihood of conflict/confusion with C++, etc. */
+ − 49
+ − 50 #define DEFAULT_BLOCK_BUFFERING_SIZE 512
+ − 51 #define MAX_READ_SIZE 512
+ − 52
+ − 53 static Lisp_Object
+ − 54 mark_lstream (Lisp_Object obj)
+ − 55 {
+ − 56 Lstream *lstr = XLSTREAM (obj);
+ − 57 return lstr->imp->marker ? (lstr->imp->marker) (obj) : Qnil;
+ − 58 }
+ − 59
+ − 60 static void
+ − 61 print_lstream (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag)
+ − 62 {
+ − 63 Lstream *lstr = XLSTREAM (obj);
+ − 64
800
+ − 65 write_fmt_string (printcharfun,
+ − 66 "#<INTERNAL OBJECT (XEmacs bug?) (%s lstream) 0x%lx>",
+ − 67 lstr->imp->name, (long) lstr);
428
+ − 68 }
+ − 69
+ − 70 static void
+ − 71 finalize_lstream (void *header, int for_disksave)
+ − 72 {
+ − 73 /* WARNING WARNING WARNING. This function (and all finalize functions)
+ − 74 may get called more than once on the same object, and may get called
+ − 75 (at dump time) on objects that are not being released. */
+ − 76 Lstream *lstr = (Lstream *) header;
+ − 77
+ − 78 #if 0 /* this may cause weird Broken Pipes? */
+ − 79 if (for_disksave)
+ − 80 {
+ − 81 Lstream_pseudo_close (lstr);
+ − 82 return;
+ − 83 }
+ − 84 #endif
+ − 85 if (lstr->flags & LSTREAM_FL_IS_OPEN)
+ − 86 {
+ − 87 if (for_disksave)
+ − 88 {
+ − 89 if (lstr->flags & LSTREAM_FL_CLOSE_AT_DISKSAVE)
+ − 90 Lstream_close (lstr);
+ − 91 }
+ − 92 else
+ − 93 /* Just close. */
+ − 94 Lstream_close (lstr);
+ − 95 }
771
+ − 96
+ − 97 if (!for_disksave)
+ − 98 {
+ − 99 if (lstr->imp->finalizer)
+ − 100 (lstr->imp->finalizer) (lstr);
+ − 101 }
428
+ − 102 }
+ − 103
665
+ − 104 inline static Bytecount
+ − 105 aligned_sizeof_lstream (Bytecount lstream_type_specific_size)
456
+ − 106 {
826
+ − 107 return MAX_ALIGN_SIZE (offsetof (Lstream, data) +
+ − 108 lstream_type_specific_size);
456
+ − 109 }
+ − 110
665
+ − 111 static Bytecount
442
+ − 112 sizeof_lstream (const void *header)
428
+ − 113 {
456
+ − 114 return aligned_sizeof_lstream (((const Lstream *) header)->imp->size);
428
+ − 115 }
+ − 116
934
+ − 117 #ifdef USE_KKCC
+ − 118 DEFINE_LRECORD_SEQUENCE_IMPLEMENTATION ("stream", lstream,
+ − 119 0, /*dumpable-flag*/
+ − 120 mark_lstream, print_lstream,
+ − 121 finalize_lstream, 0, 0, 0,
+ − 122 sizeof_lstream, Lstream);
+ − 123 #else /* not USE_KKCC */
428
+ − 124 DEFINE_LRECORD_SEQUENCE_IMPLEMENTATION ("stream", lstream,
+ − 125 mark_lstream, print_lstream,
+ − 126 finalize_lstream, 0, 0, 0,
+ − 127 sizeof_lstream, Lstream);
934
+ − 128 #endif /* not USE_KKCC */
428
+ − 129
771
+ − 130
+ − 131 /* Change the buffering of a stream. See lstream.h. By default the
+ − 132 buffering is STREAM_BLOCK_BUFFERED. */
+ − 133
428
+ − 134 void
+ − 135 Lstream_set_buffering (Lstream *lstr, Lstream_buffering buffering,
+ − 136 int buffering_size)
+ − 137 {
+ − 138 lstr->buffering = buffering;
+ − 139 switch (buffering)
+ − 140 {
+ − 141 case LSTREAM_UNBUFFERED:
+ − 142 lstr->buffering_size = 0; break;
+ − 143 case LSTREAM_BLOCK_BUFFERED:
+ − 144 lstr->buffering_size = DEFAULT_BLOCK_BUFFERING_SIZE; break;
+ − 145 case LSTREAM_BLOCKN_BUFFERED:
+ − 146 lstr->buffering_size = buffering_size; break;
+ − 147 case LSTREAM_LINE_BUFFERED:
+ − 148 case LSTREAM_UNLIMITED:
+ − 149 lstr->buffering_size = INT_MAX; break;
+ − 150 }
+ − 151 }
+ − 152
442
+ − 153 static const Lstream_implementation *lstream_types[32];
428
+ − 154 static Lisp_Object Vlstream_free_list[32];
+ − 155 static int lstream_type_count;
+ − 156
771
+ − 157 /* Allocate and return a new Lstream. This function is not really
+ − 158 meant to be called directly; rather, each stream type should
+ − 159 provide its own stream creation function, which creates the stream
+ − 160 and does any other necessary creation stuff (e.g. opening a
+ − 161 file). */
+ − 162
428
+ − 163 Lstream *
442
+ − 164 Lstream_new (const Lstream_implementation *imp, const char *mode)
428
+ − 165 {
+ − 166 Lstream *p;
+ − 167 int i;
+ − 168
+ − 169 for (i = 0; i < lstream_type_count; i++)
+ − 170 {
+ − 171 if (lstream_types[i] == imp)
+ − 172 break;
+ − 173 }
+ − 174
+ − 175 if (i == lstream_type_count)
+ − 176 {
+ − 177 assert (lstream_type_count < countof (lstream_types));
+ − 178 lstream_types[lstream_type_count] = imp;
+ − 179 Vlstream_free_list[lstream_type_count] =
456
+ − 180 make_lcrecord_list (aligned_sizeof_lstream (imp->size),
428
+ − 181 &lrecord_lstream);
+ − 182 lstream_type_count++;
+ − 183 }
+ − 184
+ − 185 p = XLSTREAM (allocate_managed_lcrecord (Vlstream_free_list[i]));
+ − 186 /* Zero it out, except the header. */
456
+ − 187 memset ((char *) p + sizeof (p->header), '\0',
+ − 188 aligned_sizeof_lstream (imp->size) - sizeof (p->header));
428
+ − 189 p->imp = imp;
+ − 190 Lstream_set_buffering (p, LSTREAM_BLOCK_BUFFERED, 0);
+ − 191 p->flags = LSTREAM_FL_IS_OPEN;
+ − 192
+ − 193 /* convert mode (one of "r", "w", "rc", "wc") to p->flags */
+ − 194 assert (mode[0] == 'r' || mode[0] == 'w');
+ − 195 assert (mode[1] == 'c' || mode[1] == '\0');
+ − 196 p->flags |= (mode[0] == 'r' ? LSTREAM_FL_READ : LSTREAM_FL_WRITE);
+ − 197 if (mode[1] == 'c')
+ − 198 p->flags |= LSTREAM_FL_NO_PARTIAL_CHARS;
+ − 199
+ − 200 return p;
+ − 201 }
+ − 202
771
+ − 203 /* Set or unset "character mode" on the stream. The basic idea is that,
+ − 204 assuming valid internal-format data is passing through the stream and
+ − 205 we're processing the data character by character, we don't want partial
+ − 206 characters at the end of the data. (No partial characters at the
+ − 207 beginning happens naturally if we eliminate partial characters at the
+ − 208 end and the stream is implemented correctly.)
+ − 209
+ − 210 Character mode actually has two somewhat different meanings, depending
+ − 211 on whether this is a read stream or write stream. If a read stream,
+ − 212 character mode means that data returned from calling Lstream_read() on
+ − 213 the stream will contain only full characters. If a write stream,
+ − 214 character mode means that data passed to the write method in the stream
+ − 215 implementation will contain only full characters. It's important to
+ − 216 note the non-parallelism in who should set this mode on the stream: The
+ − 217 *CALLER* sets character mode on read streams it creates; the *STREAM
+ − 218 ITSELF* sets character mode on write streams, typically at creation
814
+ − 219 time.
+ − 220
+ − 221 (However, if a read stream always generates internal-format data, then
+ − 222 the callers will almost always want character mode, and it's allowed to
+ − 223 set this on behalf of the caller, as long as a flag can be provided at
+ − 224 creation time to disable this behavior.) */
771
+ − 225
428
+ − 226 void
+ − 227 Lstream_set_character_mode (Lstream *lstr)
+ − 228 {
+ − 229 lstr->flags |= LSTREAM_FL_NO_PARTIAL_CHARS;
+ − 230 }
+ − 231
771
+ − 232 /* Unset character mode. See Lstream_set_character_mode(). */
+ − 233
+ − 234 void
+ − 235 Lstream_unset_character_mode (Lstream *lstr)
+ − 236 {
+ − 237 lstr->flags &= ~LSTREAM_FL_NO_PARTIAL_CHARS;
+ − 238 }
+ − 239
+ − 240 /* Close the stream (if it's open), and free all memory associated with the
+ − 241 stream. Put the stream on a free list; later calls to create a new
+ − 242 stream of this type may reuse this stream. Calling this is not strictly
+ − 243 necessary, but it is much more efficient than having the Lstream be
+ − 244 garbage-collected. Be VERY VERY SURE there are no pointers to this
+ − 245 object hanging around anywhere where they might be used! When streams
+ − 246 are chained together, be VERY CAREFUL of the order in which you delete
+ − 247 them! (e.g. if the streams are in a singly-linked list, delete the head
814
+ − 248 first; this will close (but check the documentation, e.g. of
+ − 249 make_coding_input_stream()), and may send data down to the rest. Then
771
+ − 250 proceed to the rest, one by one. If the chains are in a doubly-linked
+ − 251 list, close all the streams first (again, from the head to the tail),
+ − 252 disconnect the back links, then delete starting from the head. In
814
+ − 253 general, it's a good idea to close everything before deleting anything.
771
+ − 254
+ − 255 NOTE: DO NOT CALL DURING GARBAGE COLLECTION (e.g. in a finalizer). You
+ − 256 will be aborted. See free_managed_lcrecord(). */
+ − 257
428
+ − 258 void
+ − 259 Lstream_delete (Lstream *lstr)
+ − 260 {
+ − 261 int i;
793
+ − 262 Lisp_Object val = wrap_lstream (lstr);
428
+ − 263
+ − 264 for (i = 0; i < lstream_type_count; i++)
+ − 265 {
+ − 266 if (lstream_types[i] == lstr->imp)
+ − 267 {
+ − 268 free_managed_lcrecord (Vlstream_free_list[i], val);
+ − 269 return;
+ − 270 }
+ − 271 }
+ − 272
+ − 273 abort ();
+ − 274 }
+ − 275
+ − 276 #define Lstream_internal_error(reason, lstr) \
563
+ − 277 signal_error (Qinternal_error, reason, wrap_lstream (lstr))
428
+ − 278
771
+ − 279 /* Reopen a closed stream. This enables I/O on it again. This is not
+ − 280 meant to be called except from a wrapper routine that reinitializes
+ − 281 variables and such -- the close routine may well have freed some
+ − 282 necessary storage structures, for example. */
+ − 283
428
+ − 284 void
+ − 285 Lstream_reopen (Lstream *lstr)
+ − 286 {
+ − 287 if (lstr->flags & LSTREAM_FL_IS_OPEN)
+ − 288 Lstream_internal_error ("lstream already open", lstr);
+ − 289 lstr->flags |= LSTREAM_FL_IS_OPEN;
+ − 290 }
+ − 291
771
+ − 292 /* Try to write as much of DATA as possible to the stream. Return the
+ − 293 number of bytes written. */
428
+ − 294
771
+ − 295 static int
+ − 296 Lstream_really_write (Lstream *lstr, const unsigned char *data, int size)
428
+ − 297 {
665
+ − 298 Bytecount num_written;
771
+ − 299 const unsigned char *orig_data = data;
+ − 300 int error_occurred = 0;
428
+ − 301
771
+ − 302 while (size > 0)
428
+ − 303 {
+ − 304 if (! (lstr->flags & LSTREAM_FL_IS_OPEN))
+ − 305 Lstream_internal_error ("lstream not open", lstr);
+ − 306 if (! (lstr->flags & LSTREAM_FL_WRITE))
+ − 307 Lstream_internal_error ("lstream not open for writing", lstr);
+ − 308 if (!lstr->imp->writer)
+ − 309 Lstream_internal_error ("lstream has no writer", lstr);
+ − 310
+ − 311 if (lstr->flags & LSTREAM_FL_NO_PARTIAL_CHARS)
+ − 312 /* It's quite possible for us to get passed an incomplete
+ − 313 character at the end. We need to spit back that
+ − 314 incomplete character. */
+ − 315 {
442
+ − 316 const unsigned char *dataend = data + size - 1;
428
+ − 317 assert (size > 0); /* safety check ... */
+ − 318 /* Optimize the most common case. */
826
+ − 319 if (!byte_ascii_p (*dataend))
428
+ − 320 {
+ − 321 /* Go back to the beginning of the last (and possibly partial)
+ − 322 character, and bump forward to see if the character is
+ − 323 complete. */
867
+ − 324 VALIDATE_IBYTEPTR_BACKWARD (dataend);
826
+ − 325 if (dataend + rep_bytes_by_first_byte (*dataend) != data + size)
428
+ − 326 /* If not, chop the size down to ignore the last char
+ − 327 and stash it away for next time. */
+ − 328 size = dataend - data;
+ − 329 /* If we don't even have one character to write, then just
+ − 330 skip out. */
+ − 331 if (size == 0)
+ − 332 break;
+ − 333 }
+ − 334 }
+ − 335
771
+ − 336 num_written = (lstr->imp->writer) (lstr, data, size);
428
+ − 337 if (num_written == 0)
+ − 338 /* If nothing got written, then just hold the data. This may
+ − 339 occur, for example, if this stream does non-blocking I/O;
+ − 340 the attempt to write the data might have resulted in an
+ − 341 EWOULDBLOCK error. */
771
+ − 342 break;
+ − 343 else if (num_written > size)
+ − 344 abort ();
428
+ − 345 else if (num_written > 0)
+ − 346 {
771
+ − 347 data += num_written;
+ − 348 size -= num_written;
428
+ − 349 }
+ − 350 else
771
+ − 351 {
+ − 352 /* If error, just hold the data, for similar reasons as above. */
+ − 353 error_occurred = 1;
+ − 354 break;
+ − 355 }
428
+ − 356 }
+ − 357
+ − 358 if (lstr->imp->flusher)
771
+ − 359 error_occurred = (lstr->imp->flusher) (lstr) < 0;
+ − 360
+ − 361 if (data == orig_data && error_occurred)
+ − 362 return -1;
+ − 363
+ − 364 return data - orig_data;
+ − 365 }
+ − 366
+ − 367 /* Attempt to flush out all of the buffered data for writing. Leaves
+ − 368 whatever wasn't flushed sitting in the stream's buffers. Return -1 if
+ − 369 nothing written and error occurred, 0 otherwise. */
428
+ − 370
771
+ − 371 int
+ − 372 Lstream_flush_out (Lstream *lstr)
+ − 373 {
+ − 374 Bytecount num_written =
+ − 375 Lstream_really_write (lstr, lstr->out_buffer, lstr->out_buffer_ind);
+ − 376 if (num_written == lstr->out_buffer_ind)
+ − 377 {
+ − 378 lstr->out_buffer_ind = 0;
+ − 379 return 0;
+ − 380 }
+ − 381 else if (num_written > 0)
+ − 382 {
+ − 383 memmove (lstr->out_buffer, lstr->out_buffer + num_written,
+ − 384 lstr->out_buffer_ind - num_written);
+ − 385 lstr->out_buffer_ind -= num_written;
+ − 386 return 0;
+ − 387 }
+ − 388 else return num_written;
428
+ − 389 }
+ − 390
771
+ − 391 /* Flush out any pending unwritten data in the stream. Clear any buffered
+ − 392 input data. This differs from Lstream_flush_out() in that it also
+ − 393 clears any unflushable buffered data. Returns 0 on success, -1 on
+ − 394 error. */
+ − 395
428
+ − 396 int
+ − 397 Lstream_flush (Lstream *lstr)
+ − 398 {
+ − 399 if (Lstream_flush_out (lstr) < 0)
+ − 400 return -1;
+ − 401
+ − 402 /* clear out buffered data */
+ − 403 lstr->in_buffer_current = lstr->in_buffer_ind = 0;
+ − 404 lstr->unget_buffer_ind = 0;
+ − 405
+ − 406 return 0;
+ − 407 }
+ − 408
+ − 409 /* We want to add NUM characters. This function ensures that the
+ − 410 buffer is large enough for this (per the buffering size specified
+ − 411 in the stream) and returns the number of characters we can
+ − 412 actually write. If FORCE is set, ignore the buffering size
+ − 413 and go ahead and make space for all the chars even if it exceeds
+ − 414 the buffering size. (This is used to deal with the possibility
+ − 415 that the stream writer might refuse to write any bytes now, e.g.
+ − 416 if it's getting EWOULDBLOCK errors. We have to keep stocking them
771
+ − 417 up until they can be written, so as to avoid losing data.) */
428
+ − 418
665
+ − 419 static Bytecount
+ − 420 Lstream_adding (Lstream *lstr, Bytecount num, int force)
428
+ − 421 {
665
+ − 422 Bytecount size = num + lstr->out_buffer_ind;
430
+ − 423
+ − 424 if (size <= lstr->out_buffer_size)
+ − 425 return num;
+ − 426
428
+ − 427 /* Maybe chop it down so that we don't buffer more characters
+ − 428 than our advertised buffering size. */
430
+ − 429 if ((size > lstr->buffering_size) && !force)
+ − 430 {
+ − 431 size = lstr->buffering_size;
+ − 432 /* There might be more data buffered than the buffering size. */
+ − 433 if (size <= lstr->out_buffer_ind)
+ − 434 return 0;
+ − 435 }
+ − 436
+ − 437 DO_REALLOC (lstr->out_buffer, lstr->out_buffer_size, size, unsigned char);
+ − 438
+ − 439 return size - lstr->out_buffer_ind;
428
+ − 440 }
+ − 441
+ − 442 /* Like Lstream_write(), but does not handle line-buffering correctly. */
+ − 443
771
+ − 444 static int
665
+ − 445 Lstream_write_1 (Lstream *lstr, const void *data, Bytecount size)
428
+ − 446 {
442
+ − 447 const unsigned char *p = (const unsigned char *) data;
665
+ − 448 Bytecount off = 0;
428
+ − 449 if (! (lstr->flags & LSTREAM_FL_IS_OPEN))
+ − 450 Lstream_internal_error ("lstream not open", lstr);
+ − 451 if (! (lstr->flags & LSTREAM_FL_WRITE))
+ − 452 Lstream_internal_error ("lstream not open for writing", lstr);
771
+ − 453
+ − 454 if (lstr->buffering == LSTREAM_UNBUFFERED)
+ − 455 {
+ − 456 /* If there is buffered data, it means we ran into blocking
+ − 457 errors the previous time and had to buffer our remaining
+ − 458 data. Try to write it now. */
+ − 459 if (lstr->out_buffer_ind > 0)
+ − 460 {
+ − 461 if (Lstream_flush_out (lstr) < 0)
+ − 462 return -1;
+ − 463 }
+ − 464
+ − 465 /* If not still blocked, try to write the new data */
+ − 466 if (lstr->out_buffer_ind == 0)
+ − 467 {
+ − 468 /* we don't need to loop because Lstream_really_write does that
+ − 469 for us. */
+ − 470 Bytecount num_written = Lstream_really_write (lstr, p, size);
+ − 471 if (num_written < 0)
+ − 472 return -1;
+ − 473 off += num_written;
+ − 474 }
+ − 475
+ − 476 /* squirrel away the rest of the data */
+ − 477 if (off < size)
+ − 478 {
+ − 479 Lstream_adding (lstr, size - off, 1);
+ − 480 memcpy (lstr->out_buffer + lstr->out_buffer_ind, p + off,
+ − 481 size - off);
+ − 482 lstr->out_buffer_ind += size - off;
+ − 483 }
+ − 484
+ − 485 lstr->byte_count += size;
+ − 486 return 0;
+ − 487 }
+ − 488 else
+ − 489 {
+ − 490 int couldnt_write_last_time = 0;
428
+ − 491
771
+ − 492 while (1)
+ − 493 {
+ − 494 /* Figure out how much we can add to the buffer */
+ − 495 Bytecount chunk = Lstream_adding (lstr, size, 0);
+ − 496 if (chunk == 0)
+ − 497 {
+ − 498 if (couldnt_write_last_time)
+ − 499 /* Ung, we ran out of space and tried to flush
+ − 500 the buffer, but it didn't work because the stream
+ − 501 writer is refusing to accept any data. So we
+ − 502 just have to squirrel away all the rest of the
+ − 503 stuff. */
+ − 504 chunk = Lstream_adding (lstr, size, 1);
+ − 505 else
+ − 506 couldnt_write_last_time = 1;
+ − 507 }
+ − 508 /* Do it. */
+ − 509 if (chunk > 0)
+ − 510 {
+ − 511 memcpy (lstr->out_buffer + lstr->out_buffer_ind, p + off, chunk);
+ − 512 lstr->out_buffer_ind += chunk;
+ − 513 lstr->byte_count += chunk;
+ − 514 size -= chunk;
+ − 515 off += chunk;
+ − 516 }
+ − 517 /* If the buffer is full and we have more to add, flush it out. */
+ − 518 if (size > 0)
+ − 519 {
+ − 520 if (Lstream_flush_out (lstr) < 0)
+ − 521 {
+ − 522 if (off == 0)
+ − 523 return -1;
+ − 524 else
+ − 525 return 0;
+ − 526 }
+ − 527 }
+ − 528 else
+ − 529 break;
+ − 530 }
+ − 531 }
+ − 532 return 0;
428
+ − 533 }
+ − 534
771
+ − 535 /* Write SIZE bytes of DATA to the stream. Return value is 0 on success,
+ − 536 -1 on error. -1 is only returned when no bytes could be written; if any
+ − 537 bytes could be written, then 0 is returned and any unwritten bytes are
+ − 538 buffered and the next call to Lstream_write() will try to write them
+ − 539 again. (This buffering happens even when the stream's buffering type is
+ − 540 LSTREAM_UNBUFFERED, and regardless of how much data is passed in or what
+ − 541 the stream's buffering size was set to. #### There should perhaps be a
+ − 542 way to control whether this happens.) */
428
+ − 543
771
+ − 544 int
665
+ − 545 Lstream_write (Lstream *lstr, const void *data, Bytecount size)
428
+ − 546 {
665
+ − 547 Bytecount i;
442
+ − 548 const unsigned char *p = (const unsigned char *) data;
428
+ − 549
771
+ − 550 /* If the stream is not line-buffered, then we can just call
+ − 551 Lstream_write_1(), which writes in chunks. Otherwise, we repeatedly
+ − 552 call Lstream_putc(), which knows how to handle line buffering.
+ − 553 Returns 0 on success, -1 on failure. */
+ − 554
428
+ − 555 if (size == 0)
771
+ − 556 return 0;
428
+ − 557 if (lstr->buffering != LSTREAM_LINE_BUFFERED)
+ − 558 return Lstream_write_1 (lstr, data, size);
+ − 559 for (i = 0; i < size; i++)
+ − 560 {
+ − 561 if (Lstream_putc (lstr, p[i]) < 0)
+ − 562 break;
+ − 563 }
771
+ − 564 return i == 0 ? -1 : 0;
428
+ − 565 }
+ − 566
+ − 567 int
+ − 568 Lstream_was_blocked_p (Lstream *lstr)
+ − 569 {
+ − 570 return lstr->imp->was_blocked_p ? lstr->imp->was_blocked_p (lstr) : 0;
+ − 571 }
+ − 572
665
+ − 573 static Bytecount
462
+ − 574 Lstream_raw_read (Lstream *lstr, unsigned char *buffer,
665
+ − 575 Bytecount size)
428
+ − 576 {
+ − 577 if (! (lstr->flags & LSTREAM_FL_IS_OPEN))
+ − 578 Lstream_internal_error ("lstream not open", lstr);
+ − 579 if (! (lstr->flags & LSTREAM_FL_READ))
+ − 580 Lstream_internal_error ("lstream not open for reading", lstr);
+ − 581 if (!lstr->imp->reader)
+ − 582 Lstream_internal_error ("lstream has no reader", lstr);
+ − 583
+ − 584 return (lstr->imp->reader) (lstr, buffer, size);
+ − 585 }
+ − 586
+ − 587 /* Assuming the buffer is empty, fill it up again. */
+ − 588
665
+ − 589 static Bytecount
428
+ − 590 Lstream_read_more (Lstream *lstr)
+ − 591 {
+ − 592 #if 0
665
+ − 593 Bytecount size_needed
462
+ − 594 = max (1, min (MAX_READ_SIZE, lstr->buffering_size));
428
+ − 595 #else
+ − 596 /* If someone requested a larger buffer size, so be it! */
665
+ − 597 Bytecount size_needed =
462
+ − 598 max (1, lstr->buffering_size);
428
+ − 599 #endif
665
+ − 600 Bytecount size_gotten;
428
+ − 601
+ − 602 DO_REALLOC (lstr->in_buffer, lstr->in_buffer_size,
+ − 603 size_needed, unsigned char);
+ − 604 size_gotten = Lstream_raw_read (lstr, lstr->in_buffer, size_needed);
+ − 605 lstr->in_buffer_current = max (0, size_gotten);
+ − 606 lstr->in_buffer_ind = 0;
+ − 607 return size_gotten < 0 ? -1 : size_gotten;
+ − 608 }
+ − 609
771
+ − 610 /* Read SIZE bytes of DATA from the stream. Return the number of bytes
+ − 611 read. 0 means EOF (#### sometimes; it may simply indicate we can't read
+ − 612 any data at other times, particularly if SIZE is too small. this needs
+ − 613 to be fixed!). -1 means an error occurred and no bytes were read. */
+ − 614
814
+ − 615 static Bytecount
+ − 616 Lstream_read_1 (Lstream *lstr, void *data, Bytecount size,
+ − 617 int override_no_partial_chars)
428
+ − 618 {
+ − 619 unsigned char *p = (unsigned char *) data;
665
+ − 620 Bytecount off = 0;
+ − 621 Bytecount chunk;
428
+ − 622 int error_occurred = 0;
+ − 623
+ − 624 if (size == 0)
+ − 625 return 0;
+ − 626
+ − 627 /* First try to get some data from the unget buffer */
+ − 628 chunk = min (size, lstr->unget_buffer_ind);
+ − 629 if (chunk > 0)
+ − 630 {
+ − 631 /* The bytes come back in reverse order. */
+ − 632 for (; off < chunk; off++)
+ − 633 p[off] = lstr->unget_buffer[--lstr->unget_buffer_ind];
+ − 634 lstr->byte_count += chunk;
+ − 635 size -= chunk;
+ − 636 }
+ − 637
+ − 638 while (size > 0)
+ − 639 {
771
+ − 640 /* If unbuffered, then simply read directly into output buffer.
+ − 641 No need to copy. */
+ − 642 if (lstr->buffering == LSTREAM_UNBUFFERED)
+ − 643 {
+ − 644 chunk = Lstream_raw_read (lstr, p + off, size);
+ − 645 if (chunk < 0)
+ − 646 error_occurred = 1;
+ − 647 if (chunk <= 0)
+ − 648 break;
+ − 649 lstr->byte_count += chunk;
428
+ − 650 size -= chunk;
771
+ − 651 off += chunk;
+ − 652 }
+ − 653 else
428
+ − 654 {
771
+ − 655 /* Take whatever we can from the in buffer */
+ − 656 chunk = min (size, lstr->in_buffer_current - lstr->in_buffer_ind);
+ − 657 if (chunk > 0)
+ − 658 {
+ − 659 memcpy (p + off, lstr->in_buffer + lstr->in_buffer_ind, chunk);
+ − 660 lstr->in_buffer_ind += chunk;
+ − 661 lstr->byte_count += chunk;
+ − 662 size -= chunk;
+ − 663 off += chunk;
+ − 664 }
+ − 665
+ − 666 /* If we need some more, try to get some more from the
+ − 667 stream's end */
+ − 668 if (size > 0)
+ − 669 {
+ − 670 Bytecount retval = Lstream_read_more (lstr);
+ − 671 if (retval < 0)
+ − 672 error_occurred = 1;
+ − 673 if (retval <= 0)
+ − 674 break;
+ − 675 }
428
+ − 676 }
+ − 677 }
+ − 678
814
+ − 679 if ((lstr->flags & LSTREAM_FL_NO_PARTIAL_CHARS) &&
+ − 680 !override_no_partial_chars)
428
+ − 681 {
+ − 682 /* It's quite possible for us to get passed an incomplete
+ − 683 character at the end. We need to spit back that
+ − 684 incomplete character. */
867
+ − 685 Bytecount newoff = validate_ibyte_string_backward (p, off);
771
+ − 686 if (newoff < off)
428
+ − 687 {
771
+ − 688 Lstream_unread (lstr, p + newoff, off - newoff);
+ − 689 off = newoff;
428
+ − 690 }
+ − 691 }
+ − 692
462
+ − 693 return off == 0 && error_occurred ? -1 : off;
428
+ − 694 }
+ − 695
814
+ − 696 Bytecount
+ − 697 Lstream_read (Lstream *lstr, void *data, Bytecount size)
+ − 698 {
+ − 699 return Lstream_read_1 (lstr, data, size, 0);
+ − 700 }
+ − 701
+ − 702
771
+ − 703 /* Push back SIZE bytes of DATA onto the input queue. The next call
+ − 704 to Lstream_read() with the same size will read the same bytes back.
+ − 705 Note that this will be the case even if there is other pending
+ − 706 unread data. */
+ − 707
428
+ − 708 void
665
+ − 709 Lstream_unread (Lstream *lstr, const void *data, Bytecount size)
428
+ − 710 {
442
+ − 711 const unsigned char *p = (const unsigned char *) data;
428
+ − 712
+ − 713 /* Make sure buffer is big enough */
+ − 714 DO_REALLOC (lstr->unget_buffer, lstr->unget_buffer_size,
+ − 715 lstr->unget_buffer_ind + size, unsigned char);
+ − 716
+ − 717 lstr->byte_count -= size;
+ − 718
+ − 719 /* Bytes have to go on in reverse order -- they are reversed
+ − 720 again when read back. */
+ − 721 while (size--)
+ − 722 lstr->unget_buffer[lstr->unget_buffer_ind++] = p[size];
+ − 723 }
+ − 724
771
+ − 725 /* Rewind the stream to the beginning. */
+ − 726
428
+ − 727 int
+ − 728 Lstream_rewind (Lstream *lstr)
+ − 729 {
+ − 730 if (!lstr->imp->rewinder)
+ − 731 Lstream_internal_error ("lstream has no rewinder", lstr);
+ − 732 if (Lstream_flush (lstr) < 0)
+ − 733 return -1;
+ − 734 lstr->byte_count = 0;
+ − 735 return (lstr->imp->rewinder) (lstr);
+ − 736 }
+ − 737
+ − 738 int
+ − 739 Lstream_seekable_p (Lstream *lstr)
+ − 740 {
+ − 741 if (!lstr->imp->rewinder)
+ − 742 return 0;
+ − 743 if (!lstr->imp->seekable_p)
+ − 744 return 1;
+ − 745 return (lstr->imp->seekable_p) (lstr);
+ − 746 }
+ − 747
+ − 748 static int
+ − 749 Lstream_pseudo_close (Lstream *lstr)
+ − 750 {
+ − 751 if (!lstr->flags & LSTREAM_FL_IS_OPEN)
+ − 752 Lstream_internal_error ("lstream is not open", lstr);
+ − 753
+ − 754 /* don't check errors here -- best not to risk file descriptor loss */
+ − 755 return Lstream_flush (lstr);
+ − 756 }
+ − 757
771
+ − 758 /* Close the stream. All data will be flushed out. If the stream is
+ − 759 already closed, nothing happens. Note that, even if all data has
+ − 760 already been flushed out, the act of closing a stream may generate more
+ − 761 data -- for example, if the stream implements some sort of conversion,
+ − 762 such as gzip, there may be special "end-data" that need to be written
+ − 763 out when the file is closed. */
+ − 764
428
+ − 765 int
+ − 766 Lstream_close (Lstream *lstr)
+ − 767 {
+ − 768 int rc = 0;
+ − 769
+ − 770 if (lstr->flags & LSTREAM_FL_IS_OPEN)
+ − 771 {
+ − 772 rc = Lstream_pseudo_close (lstr);
+ − 773 /*
+ − 774 * We used to return immediately if the closer method reported
+ − 775 * failure, leaving the stream open. But this is no good, for
+ − 776 * the following reasons.
+ − 777 *
+ − 778 * 1. The finalizer method used in GC makes no provision for
+ − 779 * failure, so we must not return without freeing buffer
+ − 780 * memory.
+ − 781 *
+ − 782 * 2. The closer method may have already freed some memory
+ − 783 * used for I/O in this stream. E.g. encoding_closer frees
+ − 784 * ENCODING_STREAM_DATA(stream)->runoff. If a writer method
+ − 785 * tries to use this buffer later, it will write into memory
+ − 786 * that may have been allocated elsewhere. Sometime later
+ − 787 * you will see a sign that says "Welcome to Crash City."
+ − 788 *
+ − 789 * 3. The closer can report failure if a flush fails in the
+ − 790 * other stream in a MULE encoding/decoding stream pair.
+ − 791 * The other stream in the pair is closed, but returning
+ − 792 * early leaves the current stream open. If we try to
+ − 793 * flush the current stream later, we will crash when the
+ − 794 * flusher notices that the other end stream is closed.
+ − 795 *
+ − 796 * So, we no longer abort the close if the closer method
+ − 797 * reports some kind of failure. We still report the failure
+ − 798 * to the caller.
+ − 799 */
+ − 800 if (lstr->imp->closer)
+ − 801 if ((lstr->imp->closer) (lstr) < 0)
+ − 802 rc = -1;
+ − 803 }
+ − 804
+ − 805 lstr->flags &= ~LSTREAM_FL_IS_OPEN;
+ − 806 lstr->byte_count = 0;
+ − 807 /* Note that Lstream_flush() reset all the buffer indices. That way,
+ − 808 the next call to Lstream_putc(), Lstream_getc(), or Lstream_ungetc()
+ − 809 on a closed stream will call into the function equivalents, which will
+ − 810 cause an error. */
+ − 811
+ − 812 /* We set the pointers to 0 so that we don't lose when this function
+ − 813 is called more than once on the same object */
+ − 814 if (lstr->out_buffer)
+ − 815 {
+ − 816 xfree (lstr->out_buffer);
+ − 817 lstr->out_buffer = 0;
+ − 818 }
+ − 819 if (lstr->in_buffer)
+ − 820 {
+ − 821 xfree (lstr->in_buffer);
+ − 822 lstr->in_buffer = 0;
+ − 823 }
+ − 824 if (lstr->unget_buffer)
+ − 825 {
+ − 826 xfree (lstr->unget_buffer);
+ − 827 lstr->unget_buffer = 0;
+ − 828 }
+ − 829
+ − 830 return rc;
+ − 831 }
+ − 832
771
+ − 833
+ − 834 /* Function equivalent of Lstream_putc(). */
+ − 835
428
+ − 836 int
+ − 837 Lstream_fputc (Lstream *lstr, int c)
+ − 838 {
+ − 839 unsigned char ch = (unsigned char) c;
771
+ − 840 int retval = Lstream_write_1 (lstr, &ch, 1);
+ − 841 if (retval == 0 && lstr->buffering == LSTREAM_LINE_BUFFERED && ch == '\n')
428
+ − 842 return Lstream_flush_out (lstr);
771
+ − 843 return retval;
428
+ − 844 }
+ − 845
771
+ − 846 /* Function equivalent of Lstream_getc(). */
+ − 847
428
+ − 848 int
+ − 849 Lstream_fgetc (Lstream *lstr)
+ − 850 {
+ − 851 unsigned char ch;
814
+ − 852 if (Lstream_read_1 (lstr, &ch, 1, 1) <= 0)
428
+ − 853 return -1;
+ − 854 return ch;
+ − 855 }
+ − 856
771
+ − 857 /* Function equivalent of Lstream_ungetc(). */
+ − 858
428
+ − 859 void
+ − 860 Lstream_fungetc (Lstream *lstr, int c)
+ − 861 {
+ − 862 unsigned char ch = (unsigned char) c;
+ − 863 Lstream_unread (lstr, &ch, 1);
+ − 864 }
+ − 865
+ − 866
+ − 867 /************************ some stream implementations *********************/
+ − 868
+ − 869 /*********** a stdio stream ***********/
+ − 870
+ − 871 struct stdio_stream
+ − 872 {
+ − 873 FILE *file;
+ − 874 int closing;
+ − 875 };
+ − 876
+ − 877 #define STDIO_STREAM_DATA(stream) LSTREAM_TYPE_DATA (stream, stdio)
+ − 878
771
+ − 879 DEFINE_LSTREAM_IMPLEMENTATION ("stdio", stdio);
428
+ − 880
+ − 881 static Lisp_Object
442
+ − 882 make_stdio_stream_1 (FILE *stream, int flags, const char *mode)
428
+ − 883 {
+ − 884 Lstream *lstr = Lstream_new (lstream_stdio, mode);
+ − 885 struct stdio_stream *str = STDIO_STREAM_DATA (lstr);
+ − 886 str->file = stream;
+ − 887 str->closing = flags & LSTR_CLOSING;
+ − 888 lstr->flags |= LSTREAM_FL_CLOSE_AT_DISKSAVE;
793
+ − 889 return wrap_lstream (lstr);
428
+ − 890 }
+ − 891
+ − 892 Lisp_Object
+ − 893 make_stdio_input_stream (FILE *stream, int flags)
+ − 894 {
+ − 895 return make_stdio_stream_1 (stream, flags, "r");
+ − 896 }
+ − 897
+ − 898 Lisp_Object
+ − 899 make_stdio_output_stream (FILE *stream, int flags)
+ − 900 {
+ − 901 return make_stdio_stream_1 (stream, flags, "w");
+ − 902 }
+ − 903
+ − 904 /* #### From reading the Unix 98 specification, it appears that if we
+ − 905 want stdio_reader() to be completely correct, we should check for
+ − 906 0 < val < size and if so, check to see if an error has occurred.
+ − 907 If an error has occurred, but val is non-zero, we should go ahead
+ − 908 and act as if the read was successful, but remember in some fashion
+ − 909 or other, that an error has occurred, and report that on the next
771
+ − 910 call to stdio_reader instead of calling retry_fread() again.
428
+ − 911
771
+ − 912 Currently, in such a case, we end up calling retry_fread() twice and we
428
+ − 913 assume that
+ − 914
+ − 915 1) this is not harmful, and
+ − 916 2) the error will still be reported on the second read.
+ − 917
+ − 918 This is probably reasonable, so I don't think we should change this
+ − 919 code (it could even be argued that the error might have fixed
771
+ − 920 itself, so we should do the retry_fread() again. */
428
+ − 921
665
+ − 922 static Bytecount
+ − 923 stdio_reader (Lstream *stream, unsigned char *data, Bytecount size)
428
+ − 924 {
+ − 925 struct stdio_stream *str = STDIO_STREAM_DATA (stream);
771
+ − 926 Bytecount val = retry_fread (data, 1, size, str->file);
+ − 927 if (!val)
+ − 928 {
+ − 929 if (ferror (str->file))
+ − 930 return LSTREAM_ERROR;
+ − 931 if (feof (str->file))
+ − 932 return 0; /* LSTREAM_EOF; */
+ − 933 }
428
+ − 934 return val;
+ − 935 }
+ − 936
665
+ − 937 static Bytecount
462
+ − 938 stdio_writer (Lstream *stream, const unsigned char *data,
665
+ − 939 Bytecount size)
428
+ − 940 {
+ − 941 struct stdio_stream *str = STDIO_STREAM_DATA (stream);
771
+ − 942 Bytecount val = retry_fwrite (data, 1, size, str->file);
428
+ − 943 if (!val && ferror (str->file))
771
+ − 944 return LSTREAM_ERROR;
428
+ − 945 return val;
+ − 946 }
+ − 947
+ − 948 static int
+ − 949 stdio_rewinder (Lstream *stream)
+ − 950 {
+ − 951 rewind (STDIO_STREAM_DATA (stream)->file);
+ − 952 return 0;
+ − 953 }
+ − 954
+ − 955 static int
+ − 956 stdio_seekable_p (Lstream *stream)
+ − 957 {
+ − 958 struct stat lestat;
+ − 959 struct stdio_stream *str = STDIO_STREAM_DATA (stream);
+ − 960
771
+ − 961 if (qxe_fstat (fileno (str->file), &lestat) < 0)
428
+ − 962 return 0;
+ − 963 return S_ISREG (lestat.st_mode);
+ − 964 }
+ − 965
+ − 966 static int
+ − 967 stdio_flusher (Lstream *stream)
+ − 968 {
+ − 969 struct stdio_stream *str = STDIO_STREAM_DATA (stream);
+ − 970 if (stream->flags & LSTREAM_FL_WRITE)
+ − 971 return fflush (str->file);
+ − 972 else
+ − 973 return 0;
+ − 974 }
+ − 975
+ − 976 static int
+ − 977 stdio_closer (Lstream *stream)
+ − 978 {
+ − 979 struct stdio_stream *str = STDIO_STREAM_DATA (stream);
+ − 980 if (str->closing)
771
+ − 981 return retry_fclose (str->file);
428
+ − 982 else
+ − 983 if (stream->flags & LSTREAM_FL_WRITE)
+ − 984 return fflush (str->file);
+ − 985 else
+ − 986 return 0;
+ − 987 }
+ − 988
+ − 989 /*********** a file descriptor ***********/
+ − 990
+ − 991 struct filedesc_stream
+ − 992 {
+ − 993 int fd;
+ − 994 int pty_max_bytes;
867
+ − 995 Ibyte eof_char;
428
+ − 996 int starting_pos;
+ − 997 int current_pos;
+ − 998 int end_pos;
+ − 999 int chars_sans_newline;
+ − 1000 unsigned int closing :1;
+ − 1001 unsigned int allow_quit :1;
+ − 1002 unsigned int blocked_ok :1;
+ − 1003 unsigned int pty_flushing :1;
+ − 1004 unsigned int blocking_error_p :1;
+ − 1005 };
+ − 1006
+ − 1007 #define FILEDESC_STREAM_DATA(stream) LSTREAM_TYPE_DATA (stream, filedesc)
+ − 1008
771
+ − 1009 DEFINE_LSTREAM_IMPLEMENTATION ("filedesc", filedesc);
428
+ − 1010
+ − 1011 /* Make a stream that reads from or writes to a file descriptor FILEDESC.
+ − 1012 OFFSET is the offset from the *current* file pointer that the reading
+ − 1013 should start at. COUNT is the number of bytes to be read (it is
+ − 1014 ignored when writing); -1 for unlimited. */
+ − 1015 static Lisp_Object
+ − 1016 make_filedesc_stream_1 (int filedesc, int offset, int count, int flags,
442
+ − 1017 const char *mode)
428
+ − 1018 {
+ − 1019 Lstream *lstr = Lstream_new (lstream_filedesc, mode);
+ − 1020 struct filedesc_stream *fstr = FILEDESC_STREAM_DATA (lstr);
+ − 1021 fstr->fd = filedesc;
+ − 1022 fstr->closing = !!(flags & LSTR_CLOSING);
+ − 1023 fstr->allow_quit = !!(flags & LSTR_ALLOW_QUIT);
+ − 1024 fstr->blocked_ok = !!(flags & LSTR_BLOCKED_OK);
+ − 1025 fstr->pty_flushing = !!(flags & LSTR_PTY_FLUSHING);
+ − 1026 fstr->blocking_error_p = 0;
+ − 1027 fstr->chars_sans_newline = 0;
+ − 1028 fstr->starting_pos = lseek (filedesc, offset, SEEK_CUR);
+ − 1029 fstr->current_pos = max (fstr->starting_pos, 0);
+ − 1030 if (count < 0)
+ − 1031 fstr->end_pos = -1;
+ − 1032 else
+ − 1033 fstr->end_pos = fstr->starting_pos + count;
+ − 1034 lstr->flags |= LSTREAM_FL_CLOSE_AT_DISKSAVE;
793
+ − 1035 return wrap_lstream (lstr);
428
+ − 1036 }
+ − 1037
814
+ − 1038 /* Flags:
+ − 1039
+ − 1040 LSTR_CLOSING
+ − 1041 If set, close the descriptor or FILE * when the stream is closed.
+ − 1042
+ − 1043 LSTR_ALLOW_QUIT
+ − 1044 If set, allow quitting out of the actual I/O.
+ − 1045
+ − 1046 LSTR_PTY_FLUSHING
+ − 1047 If set and filedesc_stream_set_pty_flushing() has been called
+ − 1048 on the stream, do not send more than pty_max_bytes on a single
+ − 1049 line without flushing the data out using the eof_char.
+ − 1050
+ − 1051 LSTR_BLOCKED_OK
+ − 1052 If set, an EWOULDBLOCK error is not treated as an error but
+ − 1053 simply causes the write function to return 0 as the number
+ − 1054 of bytes written out.
+ − 1055 */
+ − 1056
428
+ − 1057 Lisp_Object
+ − 1058 make_filedesc_input_stream (int filedesc, int offset, int count, int flags)
+ − 1059 {
+ − 1060 return make_filedesc_stream_1 (filedesc, offset, count, flags, "r");
+ − 1061 }
+ − 1062
+ − 1063 Lisp_Object
+ − 1064 make_filedesc_output_stream (int filedesc, int offset, int count, int flags)
+ − 1065 {
+ − 1066 return make_filedesc_stream_1 (filedesc, offset, count, flags, "w");
+ − 1067 }
+ − 1068
665
+ − 1069 static Bytecount
+ − 1070 filedesc_reader (Lstream *stream, unsigned char *data, Bytecount size)
428
+ − 1071 {
665
+ − 1072 Bytecount nread;
428
+ − 1073 struct filedesc_stream *str = FILEDESC_STREAM_DATA (stream);
+ − 1074 if (str->end_pos >= 0)
665
+ − 1075 size = min (size, (Bytecount) (str->end_pos - str->current_pos));
430
+ − 1076 nread = str->allow_quit ?
+ − 1077 read_allowing_quit (str->fd, data, size) :
771
+ − 1078 retry_read (str->fd, data, size);
428
+ − 1079 if (nread > 0)
+ − 1080 str->current_pos += nread;
771
+ − 1081 if (nread == 0)
+ − 1082 return 0; /* LSTREAM_EOF; */
+ − 1083 if (nread < 0)
+ − 1084 return LSTREAM_ERROR;
428
+ − 1085 return nread;
+ − 1086 }
+ − 1087
+ − 1088 static int
+ − 1089 errno_would_block_p (int val)
+ − 1090 {
+ − 1091 #ifdef EWOULDBLOCK
+ − 1092 if (val == EWOULDBLOCK)
+ − 1093 return 1;
+ − 1094 #endif
+ − 1095 #ifdef EAGAIN
+ − 1096 if (val == EAGAIN)
+ − 1097 return 1;
+ − 1098 #endif
+ − 1099 return 0;
+ − 1100 }
+ − 1101
665
+ − 1102 static Bytecount
462
+ − 1103 filedesc_writer (Lstream *stream, const unsigned char *data,
665
+ − 1104 Bytecount size)
428
+ − 1105 {
+ − 1106 struct filedesc_stream *str = FILEDESC_STREAM_DATA (stream);
665
+ − 1107 Bytecount retval;
428
+ − 1108 int need_newline = 0;
+ − 1109
+ − 1110 /* This function would be simple if it were not for the blasted
+ − 1111 PTY max-bytes stuff. Why the hell can't they just have written
+ − 1112 the PTY drivers right so this problem doesn't exist?
+ − 1113
+ − 1114 Maybe all the PTY crap here should be moved into another stream
+ − 1115 that does nothing but periodically insert EOF's as necessary. */
+ − 1116 if (str->pty_flushing)
+ − 1117 {
+ − 1118 /* To make life easy, only send out one line at the most. */
442
+ − 1119 const unsigned char *ptr;
428
+ − 1120
442
+ − 1121 ptr = (const unsigned char *) memchr (data, '\n', size);
428
+ − 1122 if (ptr)
+ − 1123 need_newline = 1;
+ − 1124 else
+ − 1125 ptr = data + size;
+ − 1126 if (ptr - data >= str->pty_max_bytes - str->chars_sans_newline)
+ − 1127 {
+ − 1128 ptr = data + str->pty_max_bytes - str->chars_sans_newline;
+ − 1129 need_newline = 0;
+ − 1130 }
+ − 1131 size = ptr - data;
+ − 1132 }
+ − 1133
+ − 1134 /**** start of non-PTY-crap ****/
+ − 1135 if (size > 0)
430
+ − 1136 retval = str->allow_quit ?
+ − 1137 write_allowing_quit (str->fd, data, size) :
771
+ − 1138 retry_write (str->fd, data, size);
428
+ − 1139 else
+ − 1140 retval = 0;
+ − 1141 if (retval < 0 && errno_would_block_p (errno) && str->blocked_ok)
+ − 1142 {
+ − 1143 str->blocking_error_p = 1;
+ − 1144 return 0;
+ − 1145 }
+ − 1146 str->blocking_error_p = 0;
+ − 1147 if (retval < 0)
771
+ − 1148 return LSTREAM_ERROR;
428
+ − 1149 /**** end non-PTY-crap ****/
+ − 1150
+ − 1151 if (str->pty_flushing)
+ − 1152 {
+ − 1153 str->chars_sans_newline += retval;
+ − 1154 /* Note that a newline was not among the bytes written out.
+ − 1155 Add to the number of non-newline bytes written out,
+ − 1156 and flush with an EOF if necessary. Be careful to
+ − 1157 keep track of write errors as we go along and look
+ − 1158 out for EWOULDBLOCK. */
+ − 1159 if (str->chars_sans_newline >= str->pty_max_bytes)
+ − 1160 {
665
+ − 1161 Bytecount retval2 = str->allow_quit ?
430
+ − 1162 write_allowing_quit (str->fd, &str->eof_char, 1) :
771
+ − 1163 retry_write (str->fd, &str->eof_char, 1);
430
+ − 1164
428
+ − 1165 if (retval2 > 0)
+ − 1166 str->chars_sans_newline = 0;
+ − 1167 else if (retval2 < 0)
+ − 1168 {
+ − 1169 /* Error writing the EOF char. If nothing got written,
+ − 1170 then treat this as an error -- either return an error
+ − 1171 condition or set the blocking-error flag. */
+ − 1172 if (retval == 0)
+ − 1173 {
+ − 1174 if (errno_would_block_p (errno) && str->blocked_ok)
+ − 1175 {
+ − 1176 str->blocking_error_p = 1;
+ − 1177 return 0;
+ − 1178 }
+ − 1179 else
771
+ − 1180 return LSTREAM_ERROR;
428
+ − 1181 }
+ − 1182 else
+ − 1183 return retval;
+ − 1184 }
+ − 1185 }
+ − 1186 }
+ − 1187
+ − 1188 /* The need_newline flag is necessary because otherwise when the
+ − 1189 first byte is a newline, we'd get stuck never writing anything
+ − 1190 in pty-flushing mode. */
+ − 1191 if (need_newline)
+ − 1192 {
867
+ − 1193 Ibyte nl = '\n';
665
+ − 1194 Bytecount retval2 = str->allow_quit ?
430
+ − 1195 write_allowing_quit (str->fd, &nl, 1) :
771
+ − 1196 retry_write (str->fd, &nl, 1);
430
+ − 1197
428
+ − 1198 if (retval2 > 0)
+ − 1199 {
+ − 1200 str->chars_sans_newline = 0;
+ − 1201 retval++;
+ − 1202 }
+ − 1203 else if (retval2 < 0)
+ − 1204 {
+ − 1205 /* Error writing the newline char. If nothing got written,
+ − 1206 then treat this as an error -- either return an error
+ − 1207 condition or set the blocking-error flag. */
+ − 1208 if (retval == 0)
+ − 1209 {
+ − 1210 if (errno_would_block_p (errno) && str->blocked_ok)
+ − 1211 {
+ − 1212 str->blocking_error_p = 1;
+ − 1213 return 0;
+ − 1214 }
+ − 1215 else
771
+ − 1216 return LSTREAM_ERROR;
428
+ − 1217 }
+ − 1218 else
+ − 1219 return retval;
+ − 1220 }
+ − 1221 }
+ − 1222
+ − 1223 return retval;
+ − 1224 }
+ − 1225
+ − 1226 static int
+ − 1227 filedesc_rewinder (Lstream *stream)
+ − 1228 {
+ − 1229 struct filedesc_stream *str = FILEDESC_STREAM_DATA (stream);
+ − 1230 if (str->starting_pos < 0 ||
+ − 1231 lseek (FILEDESC_STREAM_DATA (stream)->fd, str->starting_pos,
+ − 1232 SEEK_SET) == -1)
+ − 1233 return -1;
+ − 1234 else
+ − 1235 {
+ − 1236 str->current_pos = str->starting_pos;
+ − 1237 return 0;
+ − 1238 }
+ − 1239 }
+ − 1240
+ − 1241 static int
+ − 1242 filedesc_seekable_p (Lstream *stream)
+ − 1243 {
+ − 1244 struct filedesc_stream *str = FILEDESC_STREAM_DATA (stream);
+ − 1245 if (str->starting_pos < 0)
+ − 1246 return 0;
+ − 1247 else
+ − 1248 {
+ − 1249 struct stat lestat;
+ − 1250
771
+ − 1251 if (qxe_fstat (str->fd, &lestat) < 0)
428
+ − 1252 return 0;
+ − 1253 return S_ISREG (lestat.st_mode);
+ − 1254 }
+ − 1255 }
+ − 1256
+ − 1257 static int
+ − 1258 filedesc_closer (Lstream *stream)
+ − 1259 {
+ − 1260 struct filedesc_stream *str = FILEDESC_STREAM_DATA (stream);
+ − 1261 if (str->closing)
771
+ − 1262 return retry_close (str->fd);
428
+ − 1263 else
+ − 1264 return 0;
+ − 1265 }
+ − 1266
+ − 1267 static int
+ − 1268 filedesc_was_blocked_p (Lstream *stream)
+ − 1269 {
+ − 1270 struct filedesc_stream *str = FILEDESC_STREAM_DATA (stream);
+ − 1271 return str->blocking_error_p;
+ − 1272 }
+ − 1273
+ − 1274 void
+ − 1275 filedesc_stream_set_pty_flushing (Lstream *stream, int pty_max_bytes,
867
+ − 1276 Ibyte eof_char)
428
+ − 1277 {
+ − 1278 struct filedesc_stream *str = FILEDESC_STREAM_DATA (stream);
+ − 1279 str->pty_max_bytes = pty_max_bytes;
+ − 1280 str->eof_char = eof_char;
+ − 1281 str->pty_flushing = 1;
+ − 1282 }
+ − 1283
+ − 1284 int
+ − 1285 filedesc_stream_fd (Lstream *stream)
+ − 1286 {
+ − 1287 struct filedesc_stream *str = FILEDESC_STREAM_DATA (stream);
+ − 1288 return str->fd;
+ − 1289 }
+ − 1290
+ − 1291 /*********** read from a Lisp string ***********/
+ − 1292
+ − 1293 #define LISP_STRING_STREAM_DATA(stream) LSTREAM_TYPE_DATA (stream, lisp_string)
+ − 1294
+ − 1295 struct lisp_string_stream
+ − 1296 {
+ − 1297 Lisp_Object obj;
+ − 1298 Bytecount init_offset;
+ − 1299 Bytecount offset, end;
+ − 1300 };
+ − 1301
771
+ − 1302 DEFINE_LSTREAM_IMPLEMENTATION ("lisp-string", lisp_string);
428
+ − 1303
+ − 1304 Lisp_Object
+ − 1305 make_lisp_string_input_stream (Lisp_Object string, Bytecount offset,
+ − 1306 Bytecount len)
+ − 1307 {
+ − 1308 Lstream *lstr;
+ − 1309 struct lisp_string_stream *str;
+ − 1310
+ − 1311 CHECK_STRING (string);
+ − 1312 if (len < 0)
+ − 1313 len = XSTRING_LENGTH (string) - offset;
+ − 1314 assert (offset >= 0);
+ − 1315 assert (len >= 0);
+ − 1316 assert (offset + len <= XSTRING_LENGTH (string));
+ − 1317
+ − 1318 lstr = Lstream_new (lstream_lisp_string, "r");
+ − 1319 str = LISP_STRING_STREAM_DATA (lstr);
+ − 1320 str->offset = offset;
+ − 1321 str->end = offset + len;
+ − 1322 str->init_offset = offset;
+ − 1323 str->obj = string;
793
+ − 1324 return wrap_lstream (lstr);
428
+ − 1325 }
+ − 1326
665
+ − 1327 static Bytecount
462
+ − 1328 lisp_string_reader (Lstream *stream, unsigned char *data,
665
+ − 1329 Bytecount size)
428
+ − 1330 {
+ − 1331 struct lisp_string_stream *str = LISP_STRING_STREAM_DATA (stream);
+ − 1332 /* Don't lose if the string shrank past us ... */
+ − 1333 Bytecount offset = min (str->offset, XSTRING_LENGTH (str->obj));
867
+ − 1334 Ibyte *strstart = XSTRING_DATA (str->obj);
+ − 1335 Ibyte *start = strstart + offset;
428
+ − 1336
+ − 1337 /* ... or if someone changed the string and we ended up in the
+ − 1338 middle of a character. */
+ − 1339 /* Being in the middle of a character is `normal' unless
+ − 1340 LSTREAM_NO_PARTIAL_CHARS - mrb */
+ − 1341 if (stream->flags & LSTREAM_FL_NO_PARTIAL_CHARS)
867
+ − 1342 VALIDATE_IBYTEPTR_BACKWARD (start);
428
+ − 1343 offset = start - strstart;
665
+ − 1344 size = min (size, (Bytecount) (str->end - offset));
428
+ − 1345 memcpy (data, start, size);
+ − 1346 str->offset = offset + size;
+ − 1347 return size;
+ − 1348 }
+ − 1349
+ − 1350 static int
+ − 1351 lisp_string_rewinder (Lstream *stream)
+ − 1352 {
+ − 1353 struct lisp_string_stream *str = LISP_STRING_STREAM_DATA (stream);
+ − 1354 int pos = str->init_offset;
+ − 1355 if (pos > str->end)
+ − 1356 pos = str->end;
+ − 1357 /* Don't lose if the string shrank past us ... */
+ − 1358 pos = min (pos, XSTRING_LENGTH (str->obj));
+ − 1359 /* ... or if someone changed the string and we ended up in the
+ − 1360 middle of a character. */
+ − 1361 {
867
+ − 1362 Ibyte *strstart = XSTRING_DATA (str->obj);
+ − 1363 Ibyte *start = strstart + pos;
+ − 1364 VALIDATE_IBYTEPTR_BACKWARD (start);
428
+ − 1365 pos = start - strstart;
+ − 1366 }
+ − 1367 str->offset = pos;
+ − 1368 return 0;
+ − 1369 }
+ − 1370
+ − 1371 static Lisp_Object
+ − 1372 lisp_string_marker (Lisp_Object stream)
+ − 1373 {
+ − 1374 struct lisp_string_stream *str = LISP_STRING_STREAM_DATA (XLSTREAM (stream));
+ − 1375 return str->obj;
+ − 1376 }
+ − 1377
+ − 1378 /*********** a fixed buffer ***********/
+ − 1379
+ − 1380 #define FIXED_BUFFER_STREAM_DATA(stream) \
+ − 1381 LSTREAM_TYPE_DATA (stream, fixed_buffer)
+ − 1382
+ − 1383 struct fixed_buffer_stream
+ − 1384 {
442
+ − 1385 const unsigned char *inbuf;
428
+ − 1386 unsigned char *outbuf;
665
+ − 1387 Bytecount size;
+ − 1388 Bytecount offset;
428
+ − 1389 };
+ − 1390
771
+ − 1391 DEFINE_LSTREAM_IMPLEMENTATION ("fixed-buffer", fixed_buffer);
428
+ − 1392
+ − 1393 Lisp_Object
665
+ − 1394 make_fixed_buffer_input_stream (const void *buf, Bytecount size)
428
+ − 1395 {
+ − 1396 Lstream *lstr = Lstream_new (lstream_fixed_buffer, "r");
+ − 1397 struct fixed_buffer_stream *str = FIXED_BUFFER_STREAM_DATA (lstr);
440
+ − 1398 str->inbuf = (const unsigned char *) buf;
428
+ − 1399 str->size = size;
793
+ − 1400 return wrap_lstream (lstr);
428
+ − 1401 }
+ − 1402
+ − 1403 Lisp_Object
665
+ − 1404 make_fixed_buffer_output_stream (void *buf, Bytecount size)
428
+ − 1405 {
+ − 1406 Lstream *lstr = Lstream_new (lstream_fixed_buffer, "w");
+ − 1407 struct fixed_buffer_stream *str = FIXED_BUFFER_STREAM_DATA (lstr);
440
+ − 1408 str->outbuf = (unsigned char *) buf;
428
+ − 1409 str->size = size;
793
+ − 1410 return wrap_lstream (lstr);
428
+ − 1411 }
+ − 1412
665
+ − 1413 static Bytecount
462
+ − 1414 fixed_buffer_reader (Lstream *stream, unsigned char *data,
665
+ − 1415 Bytecount size)
428
+ − 1416 {
+ − 1417 struct fixed_buffer_stream *str = FIXED_BUFFER_STREAM_DATA (stream);
+ − 1418 size = min (size, str->size - str->offset);
+ − 1419 memcpy (data, str->inbuf + str->offset, size);
+ − 1420 str->offset += size;
+ − 1421 return size;
+ − 1422 }
+ − 1423
665
+ − 1424 static Bytecount
462
+ − 1425 fixed_buffer_writer (Lstream *stream, const unsigned char *data,
665
+ − 1426 Bytecount size)
428
+ − 1427 {
+ − 1428 struct fixed_buffer_stream *str = FIXED_BUFFER_STREAM_DATA (stream);
+ − 1429 if (str->offset == str->size)
+ − 1430 {
+ − 1431 /* If we're at the end, just throw away the data and pretend
+ − 1432 we wrote all of it. If we return 0, then the lstream routines
+ − 1433 will try again and again to write it out. */
+ − 1434 return size;
+ − 1435 }
+ − 1436 size = min (size, str->size - str->offset);
+ − 1437 memcpy (str->outbuf + str->offset, data, size);
+ − 1438 str->offset += size;
+ − 1439 return size;
+ − 1440 }
+ − 1441
+ − 1442 static int
+ − 1443 fixed_buffer_rewinder (Lstream *stream)
+ − 1444 {
+ − 1445 FIXED_BUFFER_STREAM_DATA (stream)->offset = 0;
+ − 1446 return 0;
+ − 1447 }
+ − 1448
442
+ − 1449 const unsigned char *
428
+ − 1450 fixed_buffer_input_stream_ptr (Lstream *stream)
+ − 1451 {
+ − 1452 assert (stream->imp == lstream_fixed_buffer);
+ − 1453 return FIXED_BUFFER_STREAM_DATA (stream)->inbuf;
+ − 1454 }
+ − 1455
+ − 1456 unsigned char *
+ − 1457 fixed_buffer_output_stream_ptr (Lstream *stream)
+ − 1458 {
+ − 1459 assert (stream->imp == lstream_fixed_buffer);
+ − 1460 return FIXED_BUFFER_STREAM_DATA (stream)->outbuf;
+ − 1461 }
+ − 1462
+ − 1463 /*********** write to a resizing buffer ***********/
+ − 1464
+ − 1465 #define RESIZING_BUFFER_STREAM_DATA(stream) \
+ − 1466 LSTREAM_TYPE_DATA (stream, resizing_buffer)
+ − 1467
+ − 1468 struct resizing_buffer_stream
+ − 1469 {
+ − 1470 unsigned char *buf;
665
+ − 1471 Bytecount allocked;
428
+ − 1472 int max_stored;
+ − 1473 int stored;
+ − 1474 };
+ − 1475
771
+ − 1476 DEFINE_LSTREAM_IMPLEMENTATION ("resizing-buffer", resizing_buffer);
428
+ − 1477
+ − 1478 Lisp_Object
+ − 1479 make_resizing_buffer_output_stream (void)
+ − 1480 {
793
+ − 1481 return wrap_lstream (Lstream_new (lstream_resizing_buffer, "w"));
428
+ − 1482 }
+ − 1483
665
+ − 1484 static Bytecount
462
+ − 1485 resizing_buffer_writer (Lstream *stream, const unsigned char *data,
665
+ − 1486 Bytecount size)
428
+ − 1487 {
+ − 1488 struct resizing_buffer_stream *str = RESIZING_BUFFER_STREAM_DATA (stream);
+ − 1489 DO_REALLOC (str->buf, str->allocked, str->stored + size, unsigned char);
+ − 1490 memcpy (str->buf + str->stored, data, size);
+ − 1491 str->stored += size;
+ − 1492 str->max_stored = max (str->max_stored, str->stored);
+ − 1493 return size;
+ − 1494 }
+ − 1495
+ − 1496 static int
+ − 1497 resizing_buffer_rewinder (Lstream *stream)
+ − 1498 {
+ − 1499 RESIZING_BUFFER_STREAM_DATA (stream)->stored = 0;
+ − 1500 return 0;
+ − 1501 }
+ − 1502
+ − 1503 static int
+ − 1504 resizing_buffer_closer (Lstream *stream)
+ − 1505 {
+ − 1506 struct resizing_buffer_stream *str = RESIZING_BUFFER_STREAM_DATA (stream);
+ − 1507 if (str->buf)
+ − 1508 {
+ − 1509 xfree (str->buf);
+ − 1510 str->buf = 0;
+ − 1511 }
+ − 1512 return 0;
+ − 1513 }
+ − 1514
+ − 1515 unsigned char *
+ − 1516 resizing_buffer_stream_ptr (Lstream *stream)
+ − 1517 {
+ − 1518 return RESIZING_BUFFER_STREAM_DATA (stream)->buf;
+ − 1519 }
+ − 1520
788
+ − 1521 Lisp_Object
+ − 1522 resizing_buffer_to_lisp_string (Lstream *stream)
+ − 1523 {
+ − 1524 return make_string (resizing_buffer_stream_ptr (stream),
+ − 1525 Lstream_byte_count (stream));
+ − 1526 }
+ − 1527
428
+ − 1528 /*********** write to an unsigned-char dynarr ***********/
+ − 1529
+ − 1530 /* Note: If you have a dynarr whose type is not unsigned_char_dynarr
+ − 1531 but which is really just an unsigned_char_dynarr (e.g. its type
867
+ − 1532 is Ibyte or Extbyte), just cast to unsigned_char_dynarr. */
428
+ − 1533
+ − 1534 #define DYNARR_STREAM_DATA(stream) \
+ − 1535 LSTREAM_TYPE_DATA (stream, dynarr)
+ − 1536
+ − 1537 struct dynarr_stream
+ − 1538 {
+ − 1539 unsigned_char_dynarr *dyn;
+ − 1540 };
+ − 1541
771
+ − 1542 DEFINE_LSTREAM_IMPLEMENTATION ("dynarr", dynarr);
428
+ − 1543
+ − 1544 Lisp_Object
+ − 1545 make_dynarr_output_stream (unsigned_char_dynarr *dyn)
+ − 1546 {
793
+ − 1547 Lisp_Object obj = wrap_lstream (Lstream_new (lstream_dynarr, "w"));
+ − 1548
428
+ − 1549 DYNARR_STREAM_DATA (XLSTREAM (obj))->dyn = dyn;
+ − 1550 return obj;
+ − 1551 }
+ − 1552
665
+ − 1553 static Bytecount
462
+ − 1554 dynarr_writer (Lstream *stream, const unsigned char *data,
665
+ − 1555 Bytecount size)
428
+ − 1556 {
+ − 1557 struct dynarr_stream *str = DYNARR_STREAM_DATA (stream);
+ − 1558 Dynarr_add_many (str->dyn, data, size);
+ − 1559 return size;
+ − 1560 }
+ − 1561
+ − 1562 static int
+ − 1563 dynarr_rewinder (Lstream *stream)
+ − 1564 {
+ − 1565 Dynarr_reset (DYNARR_STREAM_DATA (stream)->dyn);
+ − 1566 return 0;
+ − 1567 }
+ − 1568
+ − 1569 static int
+ − 1570 dynarr_closer (Lstream *stream)
+ − 1571 {
+ − 1572 return 0;
+ − 1573 }
+ − 1574
+ − 1575 /************ read from or write to a Lisp buffer ************/
+ − 1576
+ − 1577 /* Note: Lisp-buffer read streams never return partial characters,
+ − 1578 and Lisp-buffer write streams expect to never get partial
+ − 1579 characters. */
+ − 1580
+ − 1581 #define LISP_BUFFER_STREAM_DATA(stream) \
+ − 1582 LSTREAM_TYPE_DATA (stream, lisp_buffer)
+ − 1583
+ − 1584 struct lisp_buffer_stream
+ − 1585 {
+ − 1586 Lisp_Object buffer;
+ − 1587 Lisp_Object orig_start;
+ − 1588 /* we use markers to properly deal with insertion/deletion */
+ − 1589 Lisp_Object start, end;
+ − 1590 int flags;
+ − 1591 };
+ − 1592
771
+ − 1593 DEFINE_LSTREAM_IMPLEMENTATION ("lisp-buffer", lisp_buffer);
428
+ − 1594
+ − 1595 static Lisp_Object
665
+ − 1596 make_lisp_buffer_stream_1 (struct buffer *buf, Charbpos start, Charbpos end,
826
+ − 1597 int flags, const Char_ASCII *mode)
428
+ − 1598 {
+ − 1599 Lstream *lstr;
+ − 1600 struct lisp_buffer_stream *str;
665
+ − 1601 Charbpos bmin, bmax;
428
+ − 1602 int reading = !strcmp (mode, "r");
+ − 1603
+ − 1604 /* Make sure the luser didn't pass "w" in. */
+ − 1605 if (!strcmp (mode, "w"))
+ − 1606 abort ();
+ − 1607
+ − 1608 if (flags & LSTR_IGNORE_ACCESSIBLE)
+ − 1609 {
+ − 1610 bmin = BUF_BEG (buf);
+ − 1611 bmax = BUF_Z (buf);
+ − 1612 }
+ − 1613 else
+ − 1614 {
+ − 1615 bmin = BUF_BEGV (buf);
+ − 1616 bmax = BUF_ZV (buf);
+ − 1617 }
+ − 1618
+ − 1619 if (start == -1)
+ − 1620 start = bmin;
+ − 1621 if (end == -1)
+ − 1622 end = bmax;
+ − 1623 assert (bmin <= start);
+ − 1624 assert (start <= bmax);
+ − 1625 if (reading)
+ − 1626 {
+ − 1627 assert (bmin <= end);
+ − 1628 assert (end <= bmax);
+ − 1629 assert (start <= end);
+ − 1630 }
+ − 1631
+ − 1632 lstr = Lstream_new (lstream_lisp_buffer, mode);
+ − 1633 str = LISP_BUFFER_STREAM_DATA (lstr);
+ − 1634 {
+ − 1635 Lisp_Object marker;
793
+ − 1636 Lisp_Object buffer = wrap_buffer (buf);
428
+ − 1637
+ − 1638 marker = Fmake_marker ();
+ − 1639 Fset_marker (marker, make_int (start), buffer);
+ − 1640 str->start = marker;
+ − 1641 marker = Fmake_marker ();
+ − 1642 Fset_marker (marker, make_int (start), buffer);
+ − 1643 str->orig_start = marker;
+ − 1644 if (reading)
+ − 1645 {
+ − 1646 marker = Fmake_marker ();
+ − 1647 Fset_marker (marker, make_int (end), buffer);
+ − 1648 str->end = marker;
+ − 1649 }
+ − 1650 else
+ − 1651 str->end = Qnil;
+ − 1652 str->buffer = buffer;
+ − 1653 }
+ − 1654 str->flags = flags;
793
+ − 1655 return wrap_lstream (lstr);
428
+ − 1656 }
+ − 1657
+ − 1658 Lisp_Object
826
+ − 1659 make_lisp_buffer_input_stream (struct buffer *buf, Charbpos start,
+ − 1660 Charbpos end, int flags)
428
+ − 1661 {
+ − 1662 return make_lisp_buffer_stream_1 (buf, start, end, flags, "r");
+ − 1663 }
+ − 1664
+ − 1665 Lisp_Object
665
+ − 1666 make_lisp_buffer_output_stream (struct buffer *buf, Charbpos pos, int flags)
428
+ − 1667 {
+ − 1668 Lisp_Object lstr = make_lisp_buffer_stream_1 (buf, pos, 0, flags, "wc");
+ − 1669
+ − 1670 Lstream_set_character_mode (XLSTREAM (lstr));
+ − 1671 return lstr;
+ − 1672 }
+ − 1673
665
+ − 1674 static Bytecount
867
+ − 1675 lisp_buffer_reader (Lstream *stream, Ibyte *data, Bytecount size)
428
+ − 1676 {
+ − 1677 struct lisp_buffer_stream *str = LISP_BUFFER_STREAM_DATA (stream);
665
+ − 1678 Bytebpos start;
+ − 1679 Bytebpos end;
428
+ − 1680 struct buffer *buf = XBUFFER (str->buffer);
826
+ − 1681 Bytecount src_used;
428
+ − 1682
+ − 1683 if (!BUFFER_LIVE_P (buf))
+ − 1684 return 0; /* Fut. */
+ − 1685
826
+ − 1686 start = byte_marker_position (str->start);
+ − 1687 end = byte_marker_position (str->end);
428
+ − 1688 if (!(str->flags & LSTR_IGNORE_ACCESSIBLE))
+ − 1689 {
826
+ − 1690 start = bytebpos_clip_to_bounds (BYTE_BUF_BEGV (buf), start,
+ − 1691 BYTE_BUF_ZV (buf));
+ − 1692 end = bytebpos_clip_to_bounds (BYTE_BUF_BEGV (buf), end,
+ − 1693 BYTE_BUF_ZV (buf));
428
+ − 1694 }
+ − 1695
826
+ − 1696 size = copy_buffer_text_out (buf, start, end - start, data, size,
+ − 1697 FORMAT_DEFAULT, Qnil, &src_used);
+ − 1698 end = start + src_used;
428
+ − 1699
+ − 1700 if (EQ (buf->selective_display, Qt) && str->flags & LSTR_SELECTIVE)
+ − 1701 {
+ − 1702 /* What a kludge. What a kludge. What a kludge. */
867
+ − 1703 Ibyte *p;
840
+ − 1704 for (p = data; p < data + src_used; p++)
428
+ − 1705 if (*p == '\r')
+ − 1706 *p = '\n';
+ − 1707 }
+ − 1708
826
+ − 1709 set_byte_marker_position (str->start, end);
+ − 1710 return size;
428
+ − 1711 }
+ − 1712
665
+ − 1713 static Bytecount
867
+ − 1714 lisp_buffer_writer (Lstream *stream, const Ibyte *data,
665
+ − 1715 Bytecount size)
428
+ − 1716 {
+ − 1717 struct lisp_buffer_stream *str = LISP_BUFFER_STREAM_DATA (stream);
665
+ − 1718 Charbpos pos;
428
+ − 1719 struct buffer *buf = XBUFFER (str->buffer);
+ − 1720
+ − 1721 if (!BUFFER_LIVE_P (buf))
+ − 1722 return 0; /* Fut. */
+ − 1723
+ − 1724 pos = marker_position (str->start);
+ − 1725 pos += buffer_insert_raw_string_1 (buf, pos, data, size, 0);
+ − 1726 set_marker_position (str->start, pos);
+ − 1727 return size;
+ − 1728 }
+ − 1729
+ − 1730 static int
+ − 1731 lisp_buffer_rewinder (Lstream *stream)
+ − 1732 {
+ − 1733 struct lisp_buffer_stream *str =
+ − 1734 LISP_BUFFER_STREAM_DATA (stream);
+ − 1735 struct buffer *buf = XBUFFER (str->buffer);
+ − 1736 long pos = marker_position (str->orig_start);
+ − 1737 if (!BUFFER_LIVE_P (buf))
+ − 1738 return -1; /* Fut. */
+ − 1739 if (pos > BUF_ZV (buf))
+ − 1740 pos = BUF_ZV (buf);
+ − 1741 if (pos < marker_position (str->orig_start))
+ − 1742 pos = marker_position (str->orig_start);
+ − 1743 if (MARKERP (str->end) && pos > marker_position (str->end))
+ − 1744 pos = marker_position (str->end);
+ − 1745 set_marker_position (str->start, pos);
+ − 1746 return 0;
+ − 1747 }
+ − 1748
+ − 1749 static Lisp_Object
+ − 1750 lisp_buffer_marker (Lisp_Object stream)
+ − 1751 {
+ − 1752 struct lisp_buffer_stream *str =
+ − 1753 LISP_BUFFER_STREAM_DATA (XLSTREAM (stream));
+ − 1754
+ − 1755 mark_object (str->start);
+ − 1756 mark_object (str->end);
+ − 1757 return str->buffer;
+ − 1758 }
+ − 1759
665
+ − 1760 Charbpos
428
+ − 1761 lisp_buffer_stream_startpos (Lstream *stream)
+ − 1762 {
+ − 1763 return marker_position (LISP_BUFFER_STREAM_DATA (stream)->start);
+ − 1764 }
+ − 1765
+ − 1766
+ − 1767 /************************************************************************/
+ − 1768 /* initialization */
+ − 1769 /************************************************************************/
+ − 1770
+ − 1771 void
+ − 1772 lstream_type_create (void)
+ − 1773 {
+ − 1774 LSTREAM_HAS_METHOD (stdio, reader);
+ − 1775 LSTREAM_HAS_METHOD (stdio, writer);
+ − 1776 LSTREAM_HAS_METHOD (stdio, rewinder);
+ − 1777 LSTREAM_HAS_METHOD (stdio, seekable_p);
+ − 1778 LSTREAM_HAS_METHOD (stdio, flusher);
+ − 1779 LSTREAM_HAS_METHOD (stdio, closer);
+ − 1780
+ − 1781 LSTREAM_HAS_METHOD (filedesc, reader);
+ − 1782 LSTREAM_HAS_METHOD (filedesc, writer);
+ − 1783 LSTREAM_HAS_METHOD (filedesc, was_blocked_p);
+ − 1784 LSTREAM_HAS_METHOD (filedesc, rewinder);
+ − 1785 LSTREAM_HAS_METHOD (filedesc, seekable_p);
+ − 1786 LSTREAM_HAS_METHOD (filedesc, closer);
+ − 1787
+ − 1788 LSTREAM_HAS_METHOD (lisp_string, reader);
+ − 1789 LSTREAM_HAS_METHOD (lisp_string, rewinder);
+ − 1790 LSTREAM_HAS_METHOD (lisp_string, marker);
+ − 1791
+ − 1792 LSTREAM_HAS_METHOD (fixed_buffer, reader);
+ − 1793 LSTREAM_HAS_METHOD (fixed_buffer, writer);
+ − 1794 LSTREAM_HAS_METHOD (fixed_buffer, rewinder);
+ − 1795
+ − 1796 LSTREAM_HAS_METHOD (resizing_buffer, writer);
+ − 1797 LSTREAM_HAS_METHOD (resizing_buffer, rewinder);
+ − 1798 LSTREAM_HAS_METHOD (resizing_buffer, closer);
+ − 1799
+ − 1800 LSTREAM_HAS_METHOD (dynarr, writer);
+ − 1801 LSTREAM_HAS_METHOD (dynarr, rewinder);
+ − 1802 LSTREAM_HAS_METHOD (dynarr, closer);
+ − 1803
+ − 1804 LSTREAM_HAS_METHOD (lisp_buffer, reader);
+ − 1805 LSTREAM_HAS_METHOD (lisp_buffer, writer);
+ − 1806 LSTREAM_HAS_METHOD (lisp_buffer, rewinder);
+ − 1807 LSTREAM_HAS_METHOD (lisp_buffer, marker);
+ − 1808 }
+ − 1809
+ − 1810 void
+ − 1811 reinit_vars_of_lstream (void)
+ − 1812 {
+ − 1813 int i;
+ − 1814
+ − 1815 for (i = 0; i < countof (Vlstream_free_list); i++)
+ − 1816 {
+ − 1817 Vlstream_free_list[i] = Qnil;
+ − 1818 staticpro_nodump (&Vlstream_free_list[i]);
+ − 1819 }
+ − 1820 }
+ − 1821
+ − 1822 void
+ − 1823 vars_of_lstream (void)
+ − 1824 {
442
+ − 1825 INIT_LRECORD_IMPLEMENTATION (lstream);
+ − 1826
428
+ − 1827 reinit_vars_of_lstream ();
+ − 1828 }