annotate src/lstream.c @ 665:fdefd0186b75

[xemacs-hg @ 2001-09-20 06:28:42 by ben] The great integral types renaming. The purpose of this is to rationalize the names used for various integral types, so that they match their intended uses and follow consist conventions, and eliminate types that were not semantically different from each other. The conventions are: -- All integral types that measure quantities of anything are signed. Some people disagree vociferously with this, but their arguments are mostly theoretical, and are vastly outweighed by the practical headaches of mixing signed and unsigned values, and more importantly by the far increased likelihood of inadvertent bugs: Because of the broken "viral" nature of unsigned quantities in C (operations involving mixed signed/unsigned are done unsigned, when exactly the opposite is nearly always wanted), even a single error in declaring a quantity unsigned that should be signed, or even the even more subtle error of comparing signed and unsigned values and forgetting the necessary cast, can be catastrophic, as comparisons will yield wrong results. -Wsign-compare is turned on specifically to catch this, but this tends to result in a great number of warnings when mixing signed and unsigned, and the casts are annoying. More has been written on this elsewhere. -- All such quantity types just mentioned boil down to EMACS_INT, which is 32 bits on 32-bit machines and 64 bits on 64-bit machines. This is guaranteed to be the same size as Lisp objects of type `int', and (as far as I can tell) of size_t (unsigned!) and ssize_t. The only type below that is not an EMACS_INT is Hashcode, which is an unsigned value of the same size as EMACS_INT. -- Type names should be relatively short (no more than 10 characters or so), with the first letter capitalized and no underscores if they can at all be avoided. -- "count" == a zero-based measurement of some quantity. Includes sizes, offsets, and indexes. -- "bpos" == a one-based measurement of a position in a buffer. "Charbpos" and "Bytebpos" count text in the buffer, rather than bytes in memory; thus Bytebpos does not directly correspond to the memory representation. Use "Membpos" for this. -- "Char" refers to internal-format characters, not to the C type "char", which is really a byte. -- For the actual name changes, see the script below. I ran the following script to do the conversion. (NOTE: This script is idempotent. You can safely run it multiple times and it will not screw up previous results -- in fact, it will do nothing if nothing has changed. Thus, it can be run repeatedly as necessary to handle patches coming in from old workspaces, or old branches.) There are two tags, just before and just after the change: `pre-integral-type-rename' and `post-integral-type-rename'. When merging code from the main trunk into a branch, the best thing to do is first merge up to `pre-integral-type-rename', then apply the script and associated changes, then merge from `post-integral-type-change' to the present. (Alternatively, just do the merging in one operation; but you may then have a lot of conflicts needing to be resolved by hand.) Script `fixtypes.sh' follows: ----------------------------------- cut ------------------------------------ files="*.[ch] s/*.h m/*.h config.h.in ../configure.in Makefile.in.in ../lib-src/*.[ch] ../lwlib/*.[ch]" gr Memory_Count Bytecount $files gr Lstream_Data_Count Bytecount $files gr Element_Count Elemcount $files gr Hash_Code Hashcode $files gr extcount bytecount $files gr bufpos charbpos $files gr bytind bytebpos $files gr memind membpos $files gr bufbyte intbyte $files gr Extcount Bytecount $files gr Bufpos Charbpos $files gr Bytind Bytebpos $files gr Memind Membpos $files gr Bufbyte Intbyte $files gr EXTCOUNT BYTECOUNT $files gr BUFPOS CHARBPOS $files gr BYTIND BYTEBPOS $files gr MEMIND MEMBPOS $files gr BUFBYTE INTBYTE $files gr MEMORY_COUNT BYTECOUNT $files gr LSTREAM_DATA_COUNT BYTECOUNT $files gr ELEMENT_COUNT ELEMCOUNT $files gr HASH_CODE HASHCODE $files ----------------------------------- cut ------------------------------------ `fixtypes.sh' is a Bourne-shell script; it uses 'gr': ----------------------------------- cut ------------------------------------ #!/bin/sh # Usage is like this: # gr FROM TO FILES ... # globally replace FROM with TO in FILES. FROM and TO are regular expressions. # backup files are stored in the `backup' directory. from="$1" to="$2" shift 2 echo ${1+"$@"} | xargs global-replace "s/$from/$to/g" ----------------------------------- cut ------------------------------------ `gr' in turn uses a Perl script to do its real work, `global-replace', which follows: ----------------------------------- cut ------------------------------------ : #-*- Perl -*- ### global-modify --- modify the contents of a file by a Perl expression ## Copyright (C) 1999 Martin Buchholz. ## Copyright (C) 2001 Ben Wing. ## Authors: Martin Buchholz <martin@xemacs.org>, Ben Wing <ben@xemacs.org> ## Maintainer: Ben Wing <ben@xemacs.org> ## Current Version: 1.0, May 5, 2001 # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with XEmacs; see the file COPYING. If not, write to the Free # Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. eval 'exec perl -w -S $0 ${1+"$@"}' if 0; use strict; use FileHandle; use Carp; use Getopt::Long; use File::Basename; (my $myName = $0) =~ s@.*/@@; my $usage=" Usage: $myName [--help] [--backup-dir=DIR] [--line-mode] [--hunk-mode] PERLEXPR FILE ... Globally modify a file, either line by line or in one big hunk. Typical usage is like this: [with GNU print, GNU xargs: guaranteed to handle spaces, quotes, etc. in file names] find . -name '*.[ch]' -print0 | xargs -0 $0 's/\bCONST\b/const/g'\n [with non-GNU print, xargs] find . -name '*.[ch]' -print | xargs $0 's/\bCONST\b/const/g'\n The file is read in, either line by line (with --line-mode specified) or in one big hunk (with --hunk-mode specified; it's the default), and the Perl expression is then evalled with \$_ set to the line or hunk of text, including the terminating newline if there is one. It should destructively modify the value there, storing the changed result in \$_. Files in which any modifications are made are backed up to the directory specified using --backup-dir, or to `backup' by default. To disable this, use --backup-dir= with no argument. Hunk mode is the default because it is MUCH MUCH faster than line-by-line. Use line-by-line only when it matters, e.g. you want to do a replacement only once per line (the default without the `g' argument). Conversely, when using hunk mode, *ALWAYS* use `g'; otherwise, you will only make one replacement in the entire file! "; my %options = (); $Getopt::Long::ignorecase = 0; &GetOptions ( \%options, 'help', 'backup-dir=s', 'line-mode', 'hunk-mode', ); die $usage if $options{"help"} or @ARGV <= 1; my $code = shift; die $usage if grep (-d || ! -w, @ARGV); sub SafeOpen { open ((my $fh = new FileHandle), $_[0]); confess "Can't open $_[0]: $!" if ! defined $fh; return $fh; } sub SafeClose { close $_[0] or confess "Can't close $_[0]: $!"; } sub FileContents { my $fh = SafeOpen ("< $_[0]"); my $olddollarslash = $/; local $/ = undef; my $contents = <$fh>; $/ = $olddollarslash; return $contents; } sub WriteStringToFile { my $fh = SafeOpen ("> $_[0]"); binmode $fh; print $fh $_[1] or confess "$_[0]: $!\n"; SafeClose $fh; } foreach my $file (@ARGV) { my $changed_p = 0; my $new_contents = ""; if ($options{"line-mode"}) { my $fh = SafeOpen $file; while (<$fh>) { my $save_line = $_; eval $code; $changed_p = 1 if $save_line ne $_; $new_contents .= $_; } } else { my $orig_contents = $_ = FileContents $file; eval $code; if ($_ ne $orig_contents) { $changed_p = 1; $new_contents = $_; } } if ($changed_p) { my $backdir = $options{"backup-dir"}; $backdir = "backup" if !defined ($backdir); if ($backdir) { my ($name, $path, $suffix) = fileparse ($file, ""); my $backfulldir = $path . $backdir; my $backfile = "$backfulldir/$name"; mkdir $backfulldir, 0755 unless -d $backfulldir; print "modifying $file (original saved in $backfile)\n"; rename $file, $backfile; } WriteStringToFile ($file, $new_contents); } } ----------------------------------- cut ------------------------------------ In addition to those programs, I needed to fix up a few other things, particularly relating to the duplicate definitions of types, now that some types merged with others. Specifically: 1. in lisp.h, removed duplicate declarations of Bytecount. The changed code should now look like this: (In each code snippet below, the first and last lines are the same as the original, as are all lines outside of those lines. That allows you to locate the section to be replaced, and replace the stuff in that section, verifying that there isn't anything new added that would need to be kept.) --------------------------------- snip ------------------------------------- /* Counts of bytes or chars */ typedef EMACS_INT Bytecount; typedef EMACS_INT Charcount; /* Counts of elements */ typedef EMACS_INT Elemcount; /* Hash codes */ typedef unsigned long Hashcode; /* ------------------------ dynamic arrays ------------------- */ --------------------------------- snip ------------------------------------- 2. in lstream.h, removed duplicate declaration of Bytecount. Rewrote the comment about this type. The changed code should now look like this: --------------------------------- snip ------------------------------------- #endif /* The have been some arguments over the what the type should be that specifies a count of bytes in a data block to be written out or read in, using Lstream_read(), Lstream_write(), and related functions. Originally it was long, which worked fine; Martin "corrected" these to size_t and ssize_t on the grounds that this is theoretically cleaner and is in keeping with the C standards. Unfortunately, this practice is horribly error-prone due to design flaws in the way that mixed signed/unsigned arithmetic happens. In fact, by doing this change, Martin introduced a subtle but fatal error that caused the operation of sending large mail messages to the SMTP server under Windows to fail. By putting all values back to be signed, avoiding any signed/unsigned mixing, the bug immediately went away. The type then in use was Lstream_Data_Count, so that it be reverted cleanly if a vote came to that. Now it is Bytecount. Some earlier comments about why the type must be signed: This MUST BE SIGNED, since it also is used in functions that return the number of bytes actually read to or written from in an operation, and these functions can return -1 to signal error. Note that the standard Unix read() and write() functions define the count going in as a size_t, which is UNSIGNED, and the count going out as an ssize_t, which is SIGNED. This is a horrible design flaw. Not only is it highly likely to lead to logic errors when a -1 gets interpreted as a large positive number, but operations are bound to fail in all sorts of horrible ways when a number in the upper-half of the size_t range is passed in -- this number is unrepresentable as an ssize_t, so code that checks to see how many bytes are actually written (which is mandatory if you are dealing with certain types of devices) will get completely screwed up. --ben */ typedef enum lstream_buffering --------------------------------- snip ------------------------------------- 3. in dumper.c, there are four places, all inside of switch() statements, where XD_BYTECOUNT appears twice as a case tag. In each case, the two case blocks contain identical code, and you should *REMOVE THE SECOND* and leave the first.
author ben
date Thu, 20 Sep 2001 06:31:11 +0000
parents b39c14581166
children 943eaba38521
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1 /* Generic stream implementation.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2 Copyright (C) 1995 Free Software Foundation, Inc.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3 Copyright (C) 1995 Sun Microsystems, Inc.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
4 Copyright (C) 1996 Ben Wing.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
5
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
6 This file is part of XEmacs.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
7
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
8 XEmacs is free software; you can redistribute it and/or modify it
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
9 under the terms of the GNU General Public License as published by the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
10 Free Software Foundation; either version 2, or (at your option) any
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
11 later version.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
12
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
13 XEmacs is distributed in the hope that it will be useful, but WITHOUT
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
16 for more details.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
17
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
18 You should have received a copy of the GNU General Public License
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
19 along with XEmacs; see the file COPYING. If not, write to
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
20 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
21 Boston, MA 02111-1307, USA. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
22
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
23 /* Synched up with: Not in FSF. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
24
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
25 /* Written by Ben Wing. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
26
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
27 #include <config.h>
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
28 #include "lisp.h"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
29
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
30 #include "buffer.h"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
31 #include "insdel.h"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
32 #include "lstream.h"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
33
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
34 #include "sysfile.h"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
35 #include <errno.h>
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
36
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
37 /* This function provides a generic buffering stream implementation.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
38 Conceptually, you send data to the stream or read data from the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
39 stream, not caring what's on the other end of the stream. The
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
40 other end could be another stream, a file descriptor, a stdio
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
41 stream, a fixed block of memory, a reallocating block of memory,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
42 etc. The main purpose of the stream is to provide a standard
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
43 interface and to do buffering. Macros are defined to read
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
44 or write characters, so the calling functions do not have to
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
45 worry about blocking data together in order to achieve efficiency.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
46 */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
47
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
48 /* Note that this object is called "stream" in Lisp but "lstream"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
49 in C. The reason for this is that "stream" is too generic a name
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
50 for C; too much likelihood of conflict/confusion with C++, etc. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
51
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
52 /* Functions are as follows:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
53
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
54 Lstream *Lstream_new (Lstream_implementation *imp, const char *mode)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
55 Allocate and return a new Lstream. This function is not
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
56 really meant to be called directly; rather, each stream type
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
57 should provide its own stream creation function, which
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
58 creates the stream and does any other necessary creation
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
59 stuff (e.g. opening a file).
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
60
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
61 void Lstream_set_buffering (Lstream *lstr, Lstream_buffering buffering,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
62 int buffering_size)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
63 Change the buffering of a stream. See lstream.h. By default
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
64 the buffering is STREAM_BLOCK_BUFFERED.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
65
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
66 int Lstream_flush (Lstream *lstr)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
67 Flush out any pending unwritten data in the stream. Clear
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
68 any buffered input data. Returns 0 on success, -1 on error.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
69
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
70 int Lstream_putc (Lstream *stream, int c)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
71 Write out one byte to the stream. This is a macro and so
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
72 it is very efficient. The C argument is only evaluated once
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
73 but the STREAM argument is evaluated more than once. Returns
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
74 0 on success, -1 on error.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
75
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
76 int Lstream_getc (Lstream *stream)
444
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 442
diff changeset
77 Read one byte from the stream and returns it as an unsigned
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 442
diff changeset
78 char cast to an int, or EOF on end of file or error.
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 442
diff changeset
79 This is a macro and so it is very efficient. The STREAM
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 442
diff changeset
80 argument is evaluated more than once.
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
81
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
82 void Lstream_ungetc (Lstream *stream, int c)
444
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 442
diff changeset
83 Push one byte back onto the input queue, cast to unsigned char.
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 442
diff changeset
84 This will be the next byte read from the stream. Any number
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 442
diff changeset
85 of bytes can be pushed back and will be read in the reverse
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 442
diff changeset
86 order they were pushed back -- most recent first. (This is
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 442
diff changeset
87 necessary for consistency -- if there are a number of bytes
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 442
diff changeset
88 that have been unread and I read and unread a byte, it needs
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 442
diff changeset
89 to be the first to be read again.) This is a macro and so it
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 442
diff changeset
90 is very efficient. The C argument is only evaluated once but
576fb035e263 Import from CVS: tag r21-2-37
cvs
parents: 442
diff changeset
91 the STREAM argument is evaluated more than once.
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
92
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
93 int Lstream_fputc (Lstream *stream, int c)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
94 int Lstream_fgetc (Lstream *stream)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
95 void Lstream_fungetc (Lstream *stream, int c)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
96 Function equivalents of the above macros.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
97
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
98 Bytecount Lstream_read (Lstream *stream, void *data,
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
99 Bytecount size)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
100 Read SIZE bytes of DATA from the stream. Return the number of
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
101 bytes read. 0 means EOF. -1 means an error occurred and no
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
102 bytes were read.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
103
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
104 Bytecount Lstream_write (Lstream *stream, void *data,
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
105 Bytecount size)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
106 Write SIZE bytes of DATA to the stream. Return the number of
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
107 bytes written. -1 means an error occurred and no bytes were
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
108 written.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
109
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
110 void Lstream_unread (Lstream *stream, void *data, Bytecount size)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
111 Push back SIZE bytes of DATA onto the input queue. The
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
112 next call to Lstream_read() with the same size will read the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
113 same bytes back. Note that this will be the case even if
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
114 there is other pending unread data.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
115
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
116 int Lstream_delete (Lstream *stream)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
117 Frees all memory associated with the stream is freed. Calling
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
118 this is not strictly necessary, but it is much more efficient
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
119 than having the Lstream be garbage-collected.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
120
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
121 int Lstream_close (Lstream *stream)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
122 Close the stream. All data will be flushed out.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
123
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
124 void Lstream_reopen (Lstream *stream)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
125 Reopen a closed stream. This enables I/O on it again.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
126 This is not meant to be called except from a wrapper routine
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
127 that reinitializes variables and such -- the close routine
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
128 may well have freed some necessary storage structures, for
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
129 example.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
130
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
131 void Lstream_rewind (Lstream *stream)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
132 Rewind the stream to the beginning.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
133 */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
134
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
135 #define DEFAULT_BLOCK_BUFFERING_SIZE 512
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
136 #define MAX_READ_SIZE 512
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
137
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
138 static Lisp_Object
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
139 mark_lstream (Lisp_Object obj)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
140 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
141 Lstream *lstr = XLSTREAM (obj);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
142 return lstr->imp->marker ? (lstr->imp->marker) (obj) : Qnil;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
143 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
144
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
145 static void
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
146 print_lstream (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
147 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
148 Lstream *lstr = XLSTREAM (obj);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
149 char buf[200];
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
150
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
151 sprintf (buf, "#<INTERNAL OBJECT (XEmacs bug?) (%s lstream) 0x%lx>",
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
152 lstr->imp->name, (long) lstr);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
153 write_c_string (buf, printcharfun);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
154 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
155
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
156 static void
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
157 finalize_lstream (void *header, int for_disksave)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
158 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
159 /* WARNING WARNING WARNING. This function (and all finalize functions)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
160 may get called more than once on the same object, and may get called
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
161 (at dump time) on objects that are not being released. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
162 Lstream *lstr = (Lstream *) header;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
163
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
164 #if 0 /* this may cause weird Broken Pipes? */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
165 if (for_disksave)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
166 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
167 Lstream_pseudo_close (lstr);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
168 return;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
169 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
170 #endif
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
171 if (lstr->flags & LSTREAM_FL_IS_OPEN)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
172 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
173 if (for_disksave)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
174 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
175 if (lstr->flags & LSTREAM_FL_CLOSE_AT_DISKSAVE)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
176 Lstream_close (lstr);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
177 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
178 else
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
179 /* Just close. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
180 Lstream_close (lstr);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
181 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
182 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
183
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
184 inline static Bytecount
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
185 aligned_sizeof_lstream (Bytecount lstream_type_specific_size)
456
e7ef97881643 Import from CVS: tag r21-2-43
cvs
parents: 444
diff changeset
186 {
e7ef97881643 Import from CVS: tag r21-2-43
cvs
parents: 444
diff changeset
187 return ALIGN_SIZE (offsetof (Lstream, data) + lstream_type_specific_size,
e7ef97881643 Import from CVS: tag r21-2-43
cvs
parents: 444
diff changeset
188 ALIGNOF (max_align_t));
e7ef97881643 Import from CVS: tag r21-2-43
cvs
parents: 444
diff changeset
189 }
e7ef97881643 Import from CVS: tag r21-2-43
cvs
parents: 444
diff changeset
190
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
191 static Bytecount
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
192 sizeof_lstream (const void *header)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
193 {
456
e7ef97881643 Import from CVS: tag r21-2-43
cvs
parents: 444
diff changeset
194 return aligned_sizeof_lstream (((const Lstream *) header)->imp->size);
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
195 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
196
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
197 DEFINE_LRECORD_SEQUENCE_IMPLEMENTATION ("stream", lstream,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
198 mark_lstream, print_lstream,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
199 finalize_lstream, 0, 0, 0,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
200 sizeof_lstream, Lstream);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
201
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
202 void
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
203 Lstream_set_buffering (Lstream *lstr, Lstream_buffering buffering,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
204 int buffering_size)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
205 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
206 lstr->buffering = buffering;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
207 switch (buffering)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
208 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
209 case LSTREAM_UNBUFFERED:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
210 lstr->buffering_size = 0; break;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
211 case LSTREAM_BLOCK_BUFFERED:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
212 lstr->buffering_size = DEFAULT_BLOCK_BUFFERING_SIZE; break;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
213 case LSTREAM_BLOCKN_BUFFERED:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
214 lstr->buffering_size = buffering_size; break;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
215 case LSTREAM_LINE_BUFFERED:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
216 case LSTREAM_UNLIMITED:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
217 lstr->buffering_size = INT_MAX; break;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
218 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
219 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
220
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
221 static const Lstream_implementation *lstream_types[32];
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
222 static Lisp_Object Vlstream_free_list[32];
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
223 static int lstream_type_count;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
224
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
225 Lstream *
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
226 Lstream_new (const Lstream_implementation *imp, const char *mode)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
227 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
228 Lstream *p;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
229 int i;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
230
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
231 for (i = 0; i < lstream_type_count; i++)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
232 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
233 if (lstream_types[i] == imp)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
234 break;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
235 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
236
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
237 if (i == lstream_type_count)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
238 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
239 assert (lstream_type_count < countof (lstream_types));
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
240 lstream_types[lstream_type_count] = imp;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
241 Vlstream_free_list[lstream_type_count] =
456
e7ef97881643 Import from CVS: tag r21-2-43
cvs
parents: 444
diff changeset
242 make_lcrecord_list (aligned_sizeof_lstream (imp->size),
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
243 &lrecord_lstream);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
244 lstream_type_count++;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
245 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
246
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
247 p = XLSTREAM (allocate_managed_lcrecord (Vlstream_free_list[i]));
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
248 /* Zero it out, except the header. */
456
e7ef97881643 Import from CVS: tag r21-2-43
cvs
parents: 444
diff changeset
249 memset ((char *) p + sizeof (p->header), '\0',
e7ef97881643 Import from CVS: tag r21-2-43
cvs
parents: 444
diff changeset
250 aligned_sizeof_lstream (imp->size) - sizeof (p->header));
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
251 p->imp = imp;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
252 Lstream_set_buffering (p, LSTREAM_BLOCK_BUFFERED, 0);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
253 p->flags = LSTREAM_FL_IS_OPEN;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
254
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
255 /* convert mode (one of "r", "w", "rc", "wc") to p->flags */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
256 assert (mode[0] == 'r' || mode[0] == 'w');
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
257 assert (mode[1] == 'c' || mode[1] == '\0');
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
258 p->flags |= (mode[0] == 'r' ? LSTREAM_FL_READ : LSTREAM_FL_WRITE);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
259 if (mode[1] == 'c')
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
260 p->flags |= LSTREAM_FL_NO_PARTIAL_CHARS;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
261
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
262 return p;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
263 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
264
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
265 void
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
266 Lstream_set_character_mode (Lstream *lstr)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
267 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
268 lstr->flags |= LSTREAM_FL_NO_PARTIAL_CHARS;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
269 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
270
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
271 void
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
272 Lstream_delete (Lstream *lstr)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
273 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
274 int i;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
275 Lisp_Object val;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
276
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
277 XSETLSTREAM (val, lstr);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
278 for (i = 0; i < lstream_type_count; i++)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
279 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
280 if (lstream_types[i] == lstr->imp)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
281 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
282 free_managed_lcrecord (Vlstream_free_list[i], val);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
283 return;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
284 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
285 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
286
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
287 abort ();
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
288 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
289
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
290 #define Lstream_internal_error(reason, lstr) \
563
183866b06e0b [xemacs-hg @ 2001-05-24 07:50:48 by ben]
ben
parents: 462
diff changeset
291 signal_error (Qinternal_error, reason, wrap_lstream (lstr))
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
292
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
293 void
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
294 Lstream_reopen (Lstream *lstr)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
295 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
296 if (lstr->flags & LSTREAM_FL_IS_OPEN)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
297 Lstream_internal_error ("lstream already open", lstr);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
298 lstr->flags |= LSTREAM_FL_IS_OPEN;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
299 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
300
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
301 /* Attempt to flush out all of the buffered data for writing. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
302
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
303 int
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
304 Lstream_flush_out (Lstream *lstr)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
305 {
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
306 Bytecount num_written;
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
307
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
308 while (lstr->out_buffer_ind > 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
309 {
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
310 Bytecount size = lstr->out_buffer_ind;
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
311 if (! (lstr->flags & LSTREAM_FL_IS_OPEN))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
312 Lstream_internal_error ("lstream not open", lstr);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
313 if (! (lstr->flags & LSTREAM_FL_WRITE))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
314 Lstream_internal_error ("lstream not open for writing", lstr);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
315 if (!lstr->imp->writer)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
316 Lstream_internal_error ("lstream has no writer", lstr);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
317
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
318 if (lstr->flags & LSTREAM_FL_NO_PARTIAL_CHARS)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
319 /* It's quite possible for us to get passed an incomplete
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
320 character at the end. We need to spit back that
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
321 incomplete character. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
322 {
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
323 const unsigned char *data = lstr->out_buffer;
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
324 const unsigned char *dataend = data + size - 1;
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
325 assert (size > 0); /* safety check ... */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
326 /* Optimize the most common case. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
327 if (!BYTE_ASCII_P (*dataend))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
328 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
329 /* Go back to the beginning of the last (and possibly partial)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
330 character, and bump forward to see if the character is
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
331 complete. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
332 VALIDATE_CHARPTR_BACKWARD (dataend);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
333 if (dataend + REP_BYTES_BY_FIRST_BYTE (*dataend) != data + size)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
334 /* If not, chop the size down to ignore the last char
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
335 and stash it away for next time. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
336 size = dataend - data;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
337 /* If we don't even have one character to write, then just
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
338 skip out. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
339 if (size == 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
340 break;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
341 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
342 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
343
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
344 num_written = (lstr->imp->writer) (lstr, lstr->out_buffer, size);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
345 if (num_written == 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
346 /* If nothing got written, then just hold the data. This may
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
347 occur, for example, if this stream does non-blocking I/O;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
348 the attempt to write the data might have resulted in an
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
349 EWOULDBLOCK error. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
350 return 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
351 else if (num_written >= lstr->out_buffer_ind)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
352 lstr->out_buffer_ind = 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
353 else if (num_written > 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
354 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
355 memmove (lstr->out_buffer, lstr->out_buffer + num_written,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
356 lstr->out_buffer_ind - num_written);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
357 lstr->out_buffer_ind -= num_written;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
358 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
359 else
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
360 /* If error, just hold the data, for similar reasons as above. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
361 return -1;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
362 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
363
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
364 if (lstr->imp->flusher)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
365 return (lstr->imp->flusher) (lstr);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
366
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
367 return 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
368 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
369
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
370 int
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
371 Lstream_flush (Lstream *lstr)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
372 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
373 if (Lstream_flush_out (lstr) < 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
374 return -1;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
375
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
376 /* clear out buffered data */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
377 lstr->in_buffer_current = lstr->in_buffer_ind = 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
378 lstr->unget_buffer_ind = 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
379
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
380 return 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
381 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
382
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
383 /* We want to add NUM characters. This function ensures that the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
384 buffer is large enough for this (per the buffering size specified
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
385 in the stream) and returns the number of characters we can
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
386 actually write. If FORCE is set, ignore the buffering size
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
387 and go ahead and make space for all the chars even if it exceeds
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
388 the buffering size. (This is used to deal with the possibility
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
389 that the stream writer might refuse to write any bytes now, e.g.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
390 if it's getting EWOULDBLOCK errors. We have to keep stocking them
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
391 up until they can be written, so as to avoid losing data. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
392
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
393 static Bytecount
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
394 Lstream_adding (Lstream *lstr, Bytecount num, int force)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
395 {
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
396 Bytecount size = num + lstr->out_buffer_ind;
430
a5df635868b2 Import from CVS: tag r21-2-23
cvs
parents: 428
diff changeset
397
a5df635868b2 Import from CVS: tag r21-2-23
cvs
parents: 428
diff changeset
398 if (size <= lstr->out_buffer_size)
a5df635868b2 Import from CVS: tag r21-2-23
cvs
parents: 428
diff changeset
399 return num;
a5df635868b2 Import from CVS: tag r21-2-23
cvs
parents: 428
diff changeset
400
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
401 /* Maybe chop it down so that we don't buffer more characters
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
402 than our advertised buffering size. */
430
a5df635868b2 Import from CVS: tag r21-2-23
cvs
parents: 428
diff changeset
403 if ((size > lstr->buffering_size) && !force)
a5df635868b2 Import from CVS: tag r21-2-23
cvs
parents: 428
diff changeset
404 {
a5df635868b2 Import from CVS: tag r21-2-23
cvs
parents: 428
diff changeset
405 size = lstr->buffering_size;
a5df635868b2 Import from CVS: tag r21-2-23
cvs
parents: 428
diff changeset
406 /* There might be more data buffered than the buffering size. */
a5df635868b2 Import from CVS: tag r21-2-23
cvs
parents: 428
diff changeset
407 if (size <= lstr->out_buffer_ind)
a5df635868b2 Import from CVS: tag r21-2-23
cvs
parents: 428
diff changeset
408 return 0;
a5df635868b2 Import from CVS: tag r21-2-23
cvs
parents: 428
diff changeset
409 }
a5df635868b2 Import from CVS: tag r21-2-23
cvs
parents: 428
diff changeset
410
a5df635868b2 Import from CVS: tag r21-2-23
cvs
parents: 428
diff changeset
411 DO_REALLOC (lstr->out_buffer, lstr->out_buffer_size, size, unsigned char);
a5df635868b2 Import from CVS: tag r21-2-23
cvs
parents: 428
diff changeset
412
a5df635868b2 Import from CVS: tag r21-2-23
cvs
parents: 428
diff changeset
413 return size - lstr->out_buffer_ind;
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
414 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
415
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
416 /* Like Lstream_write(), but does not handle line-buffering correctly. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
417
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
418 static Bytecount
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
419 Lstream_write_1 (Lstream *lstr, const void *data, Bytecount size)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
420 {
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
421 const unsigned char *p = (const unsigned char *) data;
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
422 Bytecount off = 0;
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
423 if (! (lstr->flags & LSTREAM_FL_IS_OPEN))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
424 Lstream_internal_error ("lstream not open", lstr);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
425 if (! (lstr->flags & LSTREAM_FL_WRITE))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
426 Lstream_internal_error ("lstream not open for writing", lstr);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
427 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
428 int couldnt_write_last_time = 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
429
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
430 while (1)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
431 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
432 /* Figure out how much we can add to the buffer */
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
433 Bytecount chunk = Lstream_adding (lstr, size, 0);
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
434 if (chunk == 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
435 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
436 if (couldnt_write_last_time)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
437 /* Ung, we ran out of space and tried to flush
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
438 the buffer, but it didn't work because the stream
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
439 writer is refusing to accept any data. So we
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
440 just have to squirrel away all the rest of the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
441 stuff. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
442 chunk = Lstream_adding (lstr, size, 1);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
443 else
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
444 couldnt_write_last_time = 1;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
445 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
446 /* Do it. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
447 if (chunk > 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
448 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
449 memcpy (lstr->out_buffer + lstr->out_buffer_ind, p + off, chunk);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
450 lstr->out_buffer_ind += chunk;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
451 lstr->byte_count += chunk;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
452 size -= chunk;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
453 off += chunk;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
454 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
455 /* If the buffer is full and we have more to add, flush it out. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
456 if (size > 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
457 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
458 if (Lstream_flush_out (lstr) < 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
459 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
460 if (off == 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
461 return -1;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
462 else
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
463 return off;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
464 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
465 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
466 else
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
467 break;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
468 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
469 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
470 return off;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
471 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
472
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
473 /* If the stream is not line-buffered, then we can just call
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
474 Lstream_write_1(), which writes in chunks. Otherwise, we
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
475 repeatedly call Lstream_putc(), which knows how to handle
440
8de8e3f6228a Import from CVS: tag r21-2-28
cvs
parents: 430
diff changeset
476 line buffering. Returns number of bytes written. */
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
477
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
478 Bytecount
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
479 Lstream_write (Lstream *lstr, const void *data, Bytecount size)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
480 {
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
481 Bytecount i;
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
482 const unsigned char *p = (const unsigned char *) data;
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
483
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
484 if (size == 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
485 return size;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
486 if (lstr->buffering != LSTREAM_LINE_BUFFERED)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
487 return Lstream_write_1 (lstr, data, size);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
488 for (i = 0; i < size; i++)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
489 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
490 if (Lstream_putc (lstr, p[i]) < 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
491 break;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
492 }
462
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents: 456
diff changeset
493 return i == 0 ? -1 : i;
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
494 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
495
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
496 int
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
497 Lstream_was_blocked_p (Lstream *lstr)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
498 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
499 return lstr->imp->was_blocked_p ? lstr->imp->was_blocked_p (lstr) : 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
500 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
501
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
502 static Bytecount
462
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents: 456
diff changeset
503 Lstream_raw_read (Lstream *lstr, unsigned char *buffer,
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
504 Bytecount size)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
505 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
506 if (! (lstr->flags & LSTREAM_FL_IS_OPEN))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
507 Lstream_internal_error ("lstream not open", lstr);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
508 if (! (lstr->flags & LSTREAM_FL_READ))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
509 Lstream_internal_error ("lstream not open for reading", lstr);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
510 if (!lstr->imp->reader)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
511 Lstream_internal_error ("lstream has no reader", lstr);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
512
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
513 return (lstr->imp->reader) (lstr, buffer, size);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
514 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
515
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
516 /* Assuming the buffer is empty, fill it up again. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
517
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
518 static Bytecount
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
519 Lstream_read_more (Lstream *lstr)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
520 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
521 #if 0
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
522 Bytecount size_needed
462
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents: 456
diff changeset
523 = max (1, min (MAX_READ_SIZE, lstr->buffering_size));
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
524 #else
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
525 /* If someone requested a larger buffer size, so be it! */
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
526 Bytecount size_needed =
462
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents: 456
diff changeset
527 max (1, lstr->buffering_size);
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
528 #endif
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
529 Bytecount size_gotten;
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
530
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
531 DO_REALLOC (lstr->in_buffer, lstr->in_buffer_size,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
532 size_needed, unsigned char);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
533 size_gotten = Lstream_raw_read (lstr, lstr->in_buffer, size_needed);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
534 lstr->in_buffer_current = max (0, size_gotten);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
535 lstr->in_buffer_ind = 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
536 return size_gotten < 0 ? -1 : size_gotten;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
537 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
538
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
539 Bytecount
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
540 Lstream_read (Lstream *lstr, void *data, Bytecount size)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
541 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
542 unsigned char *p = (unsigned char *) data;
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
543 Bytecount off = 0;
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
544 Bytecount chunk;
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
545 int error_occurred = 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
546
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
547 if (size == 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
548 return 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
549
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
550 /* First try to get some data from the unget buffer */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
551 chunk = min (size, lstr->unget_buffer_ind);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
552 if (chunk > 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
553 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
554 /* The bytes come back in reverse order. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
555 for (; off < chunk; off++)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
556 p[off] = lstr->unget_buffer[--lstr->unget_buffer_ind];
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
557 lstr->byte_count += chunk;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
558 size -= chunk;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
559 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
560
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
561 while (size > 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
562 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
563 /* Take whatever we can from the in buffer */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
564 chunk = min (size, lstr->in_buffer_current - lstr->in_buffer_ind);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
565 if (chunk > 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
566 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
567 memcpy (p + off, lstr->in_buffer + lstr->in_buffer_ind, chunk);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
568 lstr->in_buffer_ind += chunk;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
569 lstr->byte_count += chunk;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
570 size -= chunk;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
571 off += chunk;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
572 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
573
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
574 /* If we need some more, try to get some more from the stream's end */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
575 if (size > 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
576 {
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
577 Bytecount retval = Lstream_read_more (lstr);
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
578 if (retval < 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
579 error_occurred = 1;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
580 if (retval <= 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
581 break;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
582 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
583 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
584
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
585 /* #### Beware of OFF ending up 0. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
586 if ((lstr->flags & LSTREAM_FL_NO_PARTIAL_CHARS) && off > 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
587 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
588 /* It's quite possible for us to get passed an incomplete
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
589 character at the end. We need to spit back that
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
590 incomplete character. */
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
591 const unsigned char *dataend = p + off - 1;
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
592 /* Optimize the most common case. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
593 if (!BYTE_ASCII_P (*dataend))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
594 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
595 /* Go back to the beginning of the last (and possibly partial)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
596 character, and bump forward to see if the character is
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
597 complete. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
598 VALIDATE_CHARPTR_BACKWARD (dataend);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
599 if (dataend + REP_BYTES_BY_FIRST_BYTE (*dataend) != p + off)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
600 {
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
601 Bytecount newoff = dataend - p;
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
602 /* If not, chop the size down to ignore the last char
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
603 and stash it away for next time. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
604 Lstream_unread (lstr, dataend, off - newoff);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
605 off = newoff;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
606 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
607 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
608 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
609
462
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents: 456
diff changeset
610 return off == 0 && error_occurred ? -1 : off;
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
611 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
612
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
613 void
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
614 Lstream_unread (Lstream *lstr, const void *data, Bytecount size)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
615 {
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
616 const unsigned char *p = (const unsigned char *) data;
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
617
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
618 /* Make sure buffer is big enough */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
619 DO_REALLOC (lstr->unget_buffer, lstr->unget_buffer_size,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
620 lstr->unget_buffer_ind + size, unsigned char);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
621
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
622 lstr->byte_count -= size;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
623
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
624 /* Bytes have to go on in reverse order -- they are reversed
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
625 again when read back. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
626 while (size--)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
627 lstr->unget_buffer[lstr->unget_buffer_ind++] = p[size];
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
628 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
629
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
630 int
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
631 Lstream_rewind (Lstream *lstr)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
632 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
633 if (!lstr->imp->rewinder)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
634 Lstream_internal_error ("lstream has no rewinder", lstr);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
635 if (Lstream_flush (lstr) < 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
636 return -1;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
637 lstr->byte_count = 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
638 return (lstr->imp->rewinder) (lstr);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
639 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
640
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
641 int
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
642 Lstream_seekable_p (Lstream *lstr)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
643 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
644 if (!lstr->imp->rewinder)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
645 return 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
646 if (!lstr->imp->seekable_p)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
647 return 1;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
648 return (lstr->imp->seekable_p) (lstr);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
649 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
650
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
651 static int
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
652 Lstream_pseudo_close (Lstream *lstr)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
653 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
654 if (!lstr->flags & LSTREAM_FL_IS_OPEN)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
655 Lstream_internal_error ("lstream is not open", lstr);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
656
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
657 /* don't check errors here -- best not to risk file descriptor loss */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
658 return Lstream_flush (lstr);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
659 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
660
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
661 int
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
662 Lstream_close (Lstream *lstr)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
663 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
664 int rc = 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
665
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
666 if (lstr->flags & LSTREAM_FL_IS_OPEN)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
667 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
668 rc = Lstream_pseudo_close (lstr);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
669 /*
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
670 * We used to return immediately if the closer method reported
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
671 * failure, leaving the stream open. But this is no good, for
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
672 * the following reasons.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
673 *
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
674 * 1. The finalizer method used in GC makes no provision for
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
675 * failure, so we must not return without freeing buffer
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
676 * memory.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
677 *
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
678 * 2. The closer method may have already freed some memory
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
679 * used for I/O in this stream. E.g. encoding_closer frees
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
680 * ENCODING_STREAM_DATA(stream)->runoff. If a writer method
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
681 * tries to use this buffer later, it will write into memory
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
682 * that may have been allocated elsewhere. Sometime later
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
683 * you will see a sign that says "Welcome to Crash City."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
684 *
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
685 * 3. The closer can report failure if a flush fails in the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
686 * other stream in a MULE encoding/decoding stream pair.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
687 * The other stream in the pair is closed, but returning
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
688 * early leaves the current stream open. If we try to
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
689 * flush the current stream later, we will crash when the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
690 * flusher notices that the other end stream is closed.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
691 *
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
692 * So, we no longer abort the close if the closer method
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
693 * reports some kind of failure. We still report the failure
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
694 * to the caller.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
695 */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
696 if (lstr->imp->closer)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
697 if ((lstr->imp->closer) (lstr) < 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
698 rc = -1;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
699 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
700
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
701 lstr->flags &= ~LSTREAM_FL_IS_OPEN;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
702 lstr->byte_count = 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
703 /* Note that Lstream_flush() reset all the buffer indices. That way,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
704 the next call to Lstream_putc(), Lstream_getc(), or Lstream_ungetc()
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
705 on a closed stream will call into the function equivalents, which will
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
706 cause an error. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
707
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
708 /* We set the pointers to 0 so that we don't lose when this function
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
709 is called more than once on the same object */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
710 if (lstr->out_buffer)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
711 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
712 xfree (lstr->out_buffer);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
713 lstr->out_buffer = 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
714 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
715 if (lstr->in_buffer)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
716 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
717 xfree (lstr->in_buffer);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
718 lstr->in_buffer = 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
719 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
720 if (lstr->unget_buffer)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
721 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
722 xfree (lstr->unget_buffer);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
723 lstr->unget_buffer = 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
724 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
725
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
726 return rc;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
727 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
728
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
729 int
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
730 Lstream_fputc (Lstream *lstr, int c)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
731 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
732 unsigned char ch = (unsigned char) c;
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
733 Bytecount retval = Lstream_write_1 (lstr, &ch, 1);
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
734 if (retval >= 0 && lstr->buffering == LSTREAM_LINE_BUFFERED && ch == '\n')
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
735 return Lstream_flush_out (lstr);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
736 return retval < 0 ? -1 : 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
737 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
738
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
739 int
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
740 Lstream_fgetc (Lstream *lstr)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
741 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
742 unsigned char ch;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
743 if (Lstream_read (lstr, &ch, 1) <= 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
744 return -1;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
745 return ch;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
746 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
747
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
748 void
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
749 Lstream_fungetc (Lstream *lstr, int c)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
750 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
751 unsigned char ch = (unsigned char) c;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
752 Lstream_unread (lstr, &ch, 1);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
753 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
754
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
755
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
756 /************************ some stream implementations *********************/
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
757
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
758 /*********** a stdio stream ***********/
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
759
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
760 struct stdio_stream
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
761 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
762 FILE *file;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
763 int closing;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
764 };
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
765
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
766 #define STDIO_STREAM_DATA(stream) LSTREAM_TYPE_DATA (stream, stdio)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
767
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
768 DEFINE_LSTREAM_IMPLEMENTATION ("stdio", lstream_stdio,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
769 sizeof (struct stdio_stream));
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
770
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
771 static Lisp_Object
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
772 make_stdio_stream_1 (FILE *stream, int flags, const char *mode)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
773 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
774 Lisp_Object obj;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
775 Lstream *lstr = Lstream_new (lstream_stdio, mode);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
776 struct stdio_stream *str = STDIO_STREAM_DATA (lstr);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
777 str->file = stream;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
778 str->closing = flags & LSTR_CLOSING;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
779 lstr->flags |= LSTREAM_FL_CLOSE_AT_DISKSAVE;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
780 XSETLSTREAM (obj, lstr);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
781 return obj;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
782 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
783
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
784 Lisp_Object
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
785 make_stdio_input_stream (FILE *stream, int flags)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
786 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
787 return make_stdio_stream_1 (stream, flags, "r");
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
788 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
789
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
790 Lisp_Object
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
791 make_stdio_output_stream (FILE *stream, int flags)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
792 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
793 return make_stdio_stream_1 (stream, flags, "w");
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
794 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
795
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
796 /* #### From reading the Unix 98 specification, it appears that if we
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
797 want stdio_reader() to be completely correct, we should check for
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
798 0 < val < size and if so, check to see if an error has occurred.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
799 If an error has occurred, but val is non-zero, we should go ahead
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
800 and act as if the read was successful, but remember in some fashion
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
801 or other, that an error has occurred, and report that on the next
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
802 call to stdio_reader instead of calling fread() again.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
803
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
804 Currently, in such a case, we end up calling fread() twice and we
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
805 assume that
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
806
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
807 1) this is not harmful, and
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
808 2) the error will still be reported on the second read.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
809
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
810 This is probably reasonable, so I don't think we should change this
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
811 code (it could even be argued that the error might have fixed
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
812 itself, so we should do the fread() again. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
813
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
814 static Bytecount
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
815 stdio_reader (Lstream *stream, unsigned char *data, Bytecount size)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
816 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
817 struct stdio_stream *str = STDIO_STREAM_DATA (stream);
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
818 Bytecount val = fread (data, 1, size, str->file);
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
819 if (!val && ferror (str->file))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
820 return -1;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
821 return val;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
822 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
823
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
824 static Bytecount
462
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents: 456
diff changeset
825 stdio_writer (Lstream *stream, const unsigned char *data,
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
826 Bytecount size)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
827 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
828 struct stdio_stream *str = STDIO_STREAM_DATA (stream);
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
829 Bytecount val = fwrite (data, 1, size, str->file);
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
830 if (!val && ferror (str->file))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
831 return -1;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
832 return val;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
833 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
834
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
835 static int
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
836 stdio_rewinder (Lstream *stream)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
837 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
838 rewind (STDIO_STREAM_DATA (stream)->file);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
839 return 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
840 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
841
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
842 static int
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
843 stdio_seekable_p (Lstream *stream)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
844 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
845 struct stat lestat;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
846 struct stdio_stream *str = STDIO_STREAM_DATA (stream);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
847
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
848 if (fstat (fileno (str->file), &lestat) < 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
849 return 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
850 return S_ISREG (lestat.st_mode);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
851 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
852
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
853 static int
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
854 stdio_flusher (Lstream *stream)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
855 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
856 struct stdio_stream *str = STDIO_STREAM_DATA (stream);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
857 if (stream->flags & LSTREAM_FL_WRITE)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
858 return fflush (str->file);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
859 else
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
860 return 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
861 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
862
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
863 static int
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
864 stdio_closer (Lstream *stream)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
865 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
866 struct stdio_stream *str = STDIO_STREAM_DATA (stream);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
867 if (str->closing)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
868 return fclose (str->file);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
869 else
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
870 if (stream->flags & LSTREAM_FL_WRITE)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
871 return fflush (str->file);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
872 else
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
873 return 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
874 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
875
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
876 /*********** a file descriptor ***********/
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
877
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
878 struct filedesc_stream
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
879 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
880 int fd;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
881 int pty_max_bytes;
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
882 Intbyte eof_char;
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
883 int starting_pos;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
884 int current_pos;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
885 int end_pos;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
886 int chars_sans_newline;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
887 unsigned int closing :1;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
888 unsigned int allow_quit :1;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
889 unsigned int blocked_ok :1;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
890 unsigned int pty_flushing :1;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
891 unsigned int blocking_error_p :1;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
892 };
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
893
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
894 #define FILEDESC_STREAM_DATA(stream) LSTREAM_TYPE_DATA (stream, filedesc)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
895
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
896 DEFINE_LSTREAM_IMPLEMENTATION ("filedesc", lstream_filedesc,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
897 sizeof (struct filedesc_stream));
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
898
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
899 /* Make a stream that reads from or writes to a file descriptor FILEDESC.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
900 OFFSET is the offset from the *current* file pointer that the reading
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
901 should start at. COUNT is the number of bytes to be read (it is
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
902 ignored when writing); -1 for unlimited. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
903 static Lisp_Object
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
904 make_filedesc_stream_1 (int filedesc, int offset, int count, int flags,
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
905 const char *mode)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
906 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
907 Lisp_Object obj;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
908 Lstream *lstr = Lstream_new (lstream_filedesc, mode);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
909 struct filedesc_stream *fstr = FILEDESC_STREAM_DATA (lstr);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
910 fstr->fd = filedesc;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
911 fstr->closing = !!(flags & LSTR_CLOSING);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
912 fstr->allow_quit = !!(flags & LSTR_ALLOW_QUIT);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
913 fstr->blocked_ok = !!(flags & LSTR_BLOCKED_OK);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
914 fstr->pty_flushing = !!(flags & LSTR_PTY_FLUSHING);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
915 fstr->blocking_error_p = 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
916 fstr->chars_sans_newline = 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
917 fstr->starting_pos = lseek (filedesc, offset, SEEK_CUR);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
918 fstr->current_pos = max (fstr->starting_pos, 0);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
919 if (count < 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
920 fstr->end_pos = -1;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
921 else
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
922 fstr->end_pos = fstr->starting_pos + count;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
923 lstr->flags |= LSTREAM_FL_CLOSE_AT_DISKSAVE;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
924 XSETLSTREAM (obj, lstr);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
925 return obj;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
926 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
927
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
928 Lisp_Object
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
929 make_filedesc_input_stream (int filedesc, int offset, int count, int flags)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
930 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
931 return make_filedesc_stream_1 (filedesc, offset, count, flags, "r");
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
932 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
933
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
934 Lisp_Object
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
935 make_filedesc_output_stream (int filedesc, int offset, int count, int flags)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
936 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
937 return make_filedesc_stream_1 (filedesc, offset, count, flags, "w");
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
938 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
939
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
940 static Bytecount
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
941 filedesc_reader (Lstream *stream, unsigned char *data, Bytecount size)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
942 {
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
943 Bytecount nread;
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
944 struct filedesc_stream *str = FILEDESC_STREAM_DATA (stream);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
945 if (str->end_pos >= 0)
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
946 size = min (size, (Bytecount) (str->end_pos - str->current_pos));
430
a5df635868b2 Import from CVS: tag r21-2-23
cvs
parents: 428
diff changeset
947 nread = str->allow_quit ?
a5df635868b2 Import from CVS: tag r21-2-23
cvs
parents: 428
diff changeset
948 read_allowing_quit (str->fd, data, size) :
a5df635868b2 Import from CVS: tag r21-2-23
cvs
parents: 428
diff changeset
949 read (str->fd, data, size);
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
950 if (nread > 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
951 str->current_pos += nread;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
952 return nread;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
953 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
954
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
955 static int
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
956 errno_would_block_p (int val)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
957 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
958 #ifdef EWOULDBLOCK
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
959 if (val == EWOULDBLOCK)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
960 return 1;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
961 #endif
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
962 #ifdef EAGAIN
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
963 if (val == EAGAIN)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
964 return 1;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
965 #endif
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
966 return 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
967 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
968
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
969 static Bytecount
462
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents: 456
diff changeset
970 filedesc_writer (Lstream *stream, const unsigned char *data,
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
971 Bytecount size)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
972 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
973 struct filedesc_stream *str = FILEDESC_STREAM_DATA (stream);
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
974 Bytecount retval;
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
975 int need_newline = 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
976
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
977 /* This function would be simple if it were not for the blasted
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
978 PTY max-bytes stuff. Why the hell can't they just have written
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
979 the PTY drivers right so this problem doesn't exist?
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
980
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
981 Maybe all the PTY crap here should be moved into another stream
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
982 that does nothing but periodically insert EOF's as necessary. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
983 if (str->pty_flushing)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
984 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
985 /* To make life easy, only send out one line at the most. */
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
986 const unsigned char *ptr;
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
987
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
988 ptr = (const unsigned char *) memchr (data, '\n', size);
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
989 if (ptr)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
990 need_newline = 1;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
991 else
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
992 ptr = data + size;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
993 if (ptr - data >= str->pty_max_bytes - str->chars_sans_newline)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
994 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
995 ptr = data + str->pty_max_bytes - str->chars_sans_newline;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
996 need_newline = 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
997 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
998 size = ptr - data;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
999 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1000
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1001 /**** start of non-PTY-crap ****/
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1002 if (size > 0)
430
a5df635868b2 Import from CVS: tag r21-2-23
cvs
parents: 428
diff changeset
1003 retval = str->allow_quit ?
a5df635868b2 Import from CVS: tag r21-2-23
cvs
parents: 428
diff changeset
1004 write_allowing_quit (str->fd, data, size) :
a5df635868b2 Import from CVS: tag r21-2-23
cvs
parents: 428
diff changeset
1005 write (str->fd, data, size);
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1006 else
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1007 retval = 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1008 if (retval < 0 && errno_would_block_p (errno) && str->blocked_ok)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1009 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1010 str->blocking_error_p = 1;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1011 return 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1012 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1013 str->blocking_error_p = 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1014 if (retval < 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1015 return retval;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1016 /**** end non-PTY-crap ****/
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1017
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1018 if (str->pty_flushing)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1019 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1020 str->chars_sans_newline += retval;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1021 /* Note that a newline was not among the bytes written out.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1022 Add to the number of non-newline bytes written out,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1023 and flush with an EOF if necessary. Be careful to
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1024 keep track of write errors as we go along and look
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1025 out for EWOULDBLOCK. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1026 if (str->chars_sans_newline >= str->pty_max_bytes)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1027 {
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
1028 Bytecount retval2 = str->allow_quit ?
430
a5df635868b2 Import from CVS: tag r21-2-23
cvs
parents: 428
diff changeset
1029 write_allowing_quit (str->fd, &str->eof_char, 1) :
a5df635868b2 Import from CVS: tag r21-2-23
cvs
parents: 428
diff changeset
1030 write (str->fd, &str->eof_char, 1);
a5df635868b2 Import from CVS: tag r21-2-23
cvs
parents: 428
diff changeset
1031
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1032 if (retval2 > 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1033 str->chars_sans_newline = 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1034 else if (retval2 < 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1035 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1036 /* Error writing the EOF char. If nothing got written,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1037 then treat this as an error -- either return an error
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1038 condition or set the blocking-error flag. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1039 if (retval == 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1040 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1041 if (errno_would_block_p (errno) && str->blocked_ok)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1042 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1043 str->blocking_error_p = 1;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1044 return 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1045 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1046 else
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1047 return retval2;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1048 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1049 else
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1050 return retval;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1051 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1052 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1053 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1054
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1055 /* The need_newline flag is necessary because otherwise when the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1056 first byte is a newline, we'd get stuck never writing anything
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1057 in pty-flushing mode. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1058 if (need_newline)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1059 {
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
1060 Intbyte nl = '\n';
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
1061 Bytecount retval2 = str->allow_quit ?
430
a5df635868b2 Import from CVS: tag r21-2-23
cvs
parents: 428
diff changeset
1062 write_allowing_quit (str->fd, &nl, 1) :
a5df635868b2 Import from CVS: tag r21-2-23
cvs
parents: 428
diff changeset
1063 write (str->fd, &nl, 1);
a5df635868b2 Import from CVS: tag r21-2-23
cvs
parents: 428
diff changeset
1064
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1065 if (retval2 > 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1066 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1067 str->chars_sans_newline = 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1068 retval++;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1069 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1070 else if (retval2 < 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1071 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1072 /* Error writing the newline char. If nothing got written,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1073 then treat this as an error -- either return an error
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1074 condition or set the blocking-error flag. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1075 if (retval == 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1076 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1077 if (errno_would_block_p (errno) && str->blocked_ok)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1078 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1079 str->blocking_error_p = 1;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1080 return 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1081 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1082 else
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1083 return retval2;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1084 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1085 else
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1086 return retval;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1087 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1088 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1089
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1090 return retval;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1091 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1092
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1093 static int
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1094 filedesc_rewinder (Lstream *stream)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1095 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1096 struct filedesc_stream *str = FILEDESC_STREAM_DATA (stream);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1097 if (str->starting_pos < 0 ||
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1098 lseek (FILEDESC_STREAM_DATA (stream)->fd, str->starting_pos,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1099 SEEK_SET) == -1)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1100 return -1;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1101 else
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1102 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1103 str->current_pos = str->starting_pos;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1104 return 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1105 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1106 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1107
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1108 static int
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1109 filedesc_seekable_p (Lstream *stream)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1110 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1111 struct filedesc_stream *str = FILEDESC_STREAM_DATA (stream);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1112 if (str->starting_pos < 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1113 return 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1114 else
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1115 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1116 struct stat lestat;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1117
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1118 if (fstat (str->fd, &lestat) < 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1119 return 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1120 return S_ISREG (lestat.st_mode);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1121 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1122 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1123
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1124 static int
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1125 filedesc_closer (Lstream *stream)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1126 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1127 struct filedesc_stream *str = FILEDESC_STREAM_DATA (stream);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1128 if (str->closing)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1129 return close (str->fd);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1130 else
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1131 return 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1132 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1133
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1134 static int
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1135 filedesc_was_blocked_p (Lstream *stream)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1136 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1137 struct filedesc_stream *str = FILEDESC_STREAM_DATA (stream);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1138 return str->blocking_error_p;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1139 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1140
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1141 void
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1142 filedesc_stream_set_pty_flushing (Lstream *stream, int pty_max_bytes,
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
1143 Intbyte eof_char)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1144 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1145 struct filedesc_stream *str = FILEDESC_STREAM_DATA (stream);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1146 str->pty_max_bytes = pty_max_bytes;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1147 str->eof_char = eof_char;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1148 str->pty_flushing = 1;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1149 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1150
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1151 int
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1152 filedesc_stream_fd (Lstream *stream)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1153 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1154 struct filedesc_stream *str = FILEDESC_STREAM_DATA (stream);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1155 return str->fd;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1156 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1157
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1158 /*********** read from a Lisp string ***********/
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1159
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1160 #define LISP_STRING_STREAM_DATA(stream) LSTREAM_TYPE_DATA (stream, lisp_string)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1161
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1162 struct lisp_string_stream
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1163 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1164 Lisp_Object obj;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1165 Bytecount init_offset;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1166 Bytecount offset, end;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1167 };
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1168
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1169 DEFINE_LSTREAM_IMPLEMENTATION ("lisp-string", lstream_lisp_string,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1170 sizeof (struct lisp_string_stream));
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1171
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1172 Lisp_Object
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1173 make_lisp_string_input_stream (Lisp_Object string, Bytecount offset,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1174 Bytecount len)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1175 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1176 Lisp_Object obj;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1177 Lstream *lstr;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1178 struct lisp_string_stream *str;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1179
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1180 CHECK_STRING (string);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1181 if (len < 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1182 len = XSTRING_LENGTH (string) - offset;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1183 assert (offset >= 0);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1184 assert (len >= 0);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1185 assert (offset + len <= XSTRING_LENGTH (string));
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1186
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1187 lstr = Lstream_new (lstream_lisp_string, "r");
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1188 str = LISP_STRING_STREAM_DATA (lstr);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1189 str->offset = offset;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1190 str->end = offset + len;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1191 str->init_offset = offset;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1192 str->obj = string;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1193 XSETLSTREAM (obj, lstr);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1194 return obj;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1195 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1196
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
1197 static Bytecount
462
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents: 456
diff changeset
1198 lisp_string_reader (Lstream *stream, unsigned char *data,
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
1199 Bytecount size)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1200 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1201 struct lisp_string_stream *str = LISP_STRING_STREAM_DATA (stream);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1202 /* Don't lose if the string shrank past us ... */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1203 Bytecount offset = min (str->offset, XSTRING_LENGTH (str->obj));
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
1204 Intbyte *strstart = XSTRING_DATA (str->obj);
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
1205 Intbyte *start = strstart + offset;
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1206
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1207 /* ... or if someone changed the string and we ended up in the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1208 middle of a character. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1209 /* Being in the middle of a character is `normal' unless
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1210 LSTREAM_NO_PARTIAL_CHARS - mrb */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1211 if (stream->flags & LSTREAM_FL_NO_PARTIAL_CHARS)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1212 VALIDATE_CHARPTR_BACKWARD (start);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1213 offset = start - strstart;
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
1214 size = min (size, (Bytecount) (str->end - offset));
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1215 memcpy (data, start, size);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1216 str->offset = offset + size;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1217 return size;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1218 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1219
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1220 static int
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1221 lisp_string_rewinder (Lstream *stream)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1222 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1223 struct lisp_string_stream *str = LISP_STRING_STREAM_DATA (stream);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1224 int pos = str->init_offset;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1225 if (pos > str->end)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1226 pos = str->end;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1227 /* Don't lose if the string shrank past us ... */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1228 pos = min (pos, XSTRING_LENGTH (str->obj));
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1229 /* ... or if someone changed the string and we ended up in the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1230 middle of a character. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1231 {
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
1232 Intbyte *strstart = XSTRING_DATA (str->obj);
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
1233 Intbyte *start = strstart + pos;
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1234 VALIDATE_CHARPTR_BACKWARD (start);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1235 pos = start - strstart;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1236 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1237 str->offset = pos;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1238 return 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1239 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1240
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1241 static Lisp_Object
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1242 lisp_string_marker (Lisp_Object stream)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1243 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1244 struct lisp_string_stream *str = LISP_STRING_STREAM_DATA (XLSTREAM (stream));
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1245 return str->obj;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1246 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1247
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1248 /*********** a fixed buffer ***********/
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1249
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1250 #define FIXED_BUFFER_STREAM_DATA(stream) \
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1251 LSTREAM_TYPE_DATA (stream, fixed_buffer)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1252
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1253 struct fixed_buffer_stream
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1254 {
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
1255 const unsigned char *inbuf;
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1256 unsigned char *outbuf;
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
1257 Bytecount size;
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
1258 Bytecount offset;
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1259 };
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1260
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1261 DEFINE_LSTREAM_IMPLEMENTATION ("fixed-buffer", lstream_fixed_buffer,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1262 sizeof (struct fixed_buffer_stream));
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1263
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1264 Lisp_Object
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
1265 make_fixed_buffer_input_stream (const void *buf, Bytecount size)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1266 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1267 Lisp_Object obj;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1268 Lstream *lstr = Lstream_new (lstream_fixed_buffer, "r");
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1269 struct fixed_buffer_stream *str = FIXED_BUFFER_STREAM_DATA (lstr);
440
8de8e3f6228a Import from CVS: tag r21-2-28
cvs
parents: 430
diff changeset
1270 str->inbuf = (const unsigned char *) buf;
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1271 str->size = size;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1272 XSETLSTREAM (obj, lstr);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1273 return obj;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1274 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1275
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1276 Lisp_Object
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
1277 make_fixed_buffer_output_stream (void *buf, Bytecount size)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1278 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1279 Lisp_Object obj;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1280 Lstream *lstr = Lstream_new (lstream_fixed_buffer, "w");
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1281 struct fixed_buffer_stream *str = FIXED_BUFFER_STREAM_DATA (lstr);
440
8de8e3f6228a Import from CVS: tag r21-2-28
cvs
parents: 430
diff changeset
1282 str->outbuf = (unsigned char *) buf;
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1283 str->size = size;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1284 XSETLSTREAM (obj, lstr);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1285 return obj;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1286 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1287
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
1288 static Bytecount
462
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents: 456
diff changeset
1289 fixed_buffer_reader (Lstream *stream, unsigned char *data,
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
1290 Bytecount size)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1291 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1292 struct fixed_buffer_stream *str = FIXED_BUFFER_STREAM_DATA (stream);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1293 size = min (size, str->size - str->offset);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1294 memcpy (data, str->inbuf + str->offset, size);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1295 str->offset += size;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1296 return size;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1297 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1298
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
1299 static Bytecount
462
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents: 456
diff changeset
1300 fixed_buffer_writer (Lstream *stream, const unsigned char *data,
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
1301 Bytecount size)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1302 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1303 struct fixed_buffer_stream *str = FIXED_BUFFER_STREAM_DATA (stream);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1304 if (str->offset == str->size)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1305 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1306 /* If we're at the end, just throw away the data and pretend
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1307 we wrote all of it. If we return 0, then the lstream routines
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1308 will try again and again to write it out. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1309 return size;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1310 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1311 size = min (size, str->size - str->offset);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1312 memcpy (str->outbuf + str->offset, data, size);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1313 str->offset += size;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1314 return size;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1315 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1316
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1317 static int
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1318 fixed_buffer_rewinder (Lstream *stream)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1319 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1320 FIXED_BUFFER_STREAM_DATA (stream)->offset = 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1321 return 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1322 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1323
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
1324 const unsigned char *
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1325 fixed_buffer_input_stream_ptr (Lstream *stream)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1326 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1327 assert (stream->imp == lstream_fixed_buffer);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1328 return FIXED_BUFFER_STREAM_DATA (stream)->inbuf;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1329 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1330
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1331 unsigned char *
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1332 fixed_buffer_output_stream_ptr (Lstream *stream)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1333 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1334 assert (stream->imp == lstream_fixed_buffer);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1335 return FIXED_BUFFER_STREAM_DATA (stream)->outbuf;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1336 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1337
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1338 /*********** write to a resizing buffer ***********/
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1339
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1340 #define RESIZING_BUFFER_STREAM_DATA(stream) \
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1341 LSTREAM_TYPE_DATA (stream, resizing_buffer)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1342
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1343 struct resizing_buffer_stream
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1344 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1345 unsigned char *buf;
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
1346 Bytecount allocked;
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1347 int max_stored;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1348 int stored;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1349 };
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1350
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1351 DEFINE_LSTREAM_IMPLEMENTATION ("resizing-buffer", lstream_resizing_buffer,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1352 sizeof (struct resizing_buffer_stream));
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1353
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1354 Lisp_Object
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1355 make_resizing_buffer_output_stream (void)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1356 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1357 Lisp_Object obj;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1358 XSETLSTREAM (obj, Lstream_new (lstream_resizing_buffer, "w"));
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1359 return obj;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1360 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1361
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
1362 static Bytecount
462
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents: 456
diff changeset
1363 resizing_buffer_writer (Lstream *stream, const unsigned char *data,
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
1364 Bytecount size)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1365 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1366 struct resizing_buffer_stream *str = RESIZING_BUFFER_STREAM_DATA (stream);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1367 DO_REALLOC (str->buf, str->allocked, str->stored + size, unsigned char);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1368 memcpy (str->buf + str->stored, data, size);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1369 str->stored += size;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1370 str->max_stored = max (str->max_stored, str->stored);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1371 return size;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1372 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1373
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1374 static int
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1375 resizing_buffer_rewinder (Lstream *stream)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1376 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1377 RESIZING_BUFFER_STREAM_DATA (stream)->stored = 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1378 return 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1379 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1380
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1381 static int
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1382 resizing_buffer_closer (Lstream *stream)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1383 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1384 struct resizing_buffer_stream *str = RESIZING_BUFFER_STREAM_DATA (stream);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1385 if (str->buf)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1386 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1387 xfree (str->buf);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1388 str->buf = 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1389 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1390 return 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1391 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1392
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1393 unsigned char *
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1394 resizing_buffer_stream_ptr (Lstream *stream)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1395 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1396 return RESIZING_BUFFER_STREAM_DATA (stream)->buf;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1397 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1398
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1399 /*********** write to an unsigned-char dynarr ***********/
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1400
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1401 /* Note: If you have a dynarr whose type is not unsigned_char_dynarr
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1402 but which is really just an unsigned_char_dynarr (e.g. its type
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
1403 is Intbyte or Extbyte), just cast to unsigned_char_dynarr. */
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1404
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1405 #define DYNARR_STREAM_DATA(stream) \
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1406 LSTREAM_TYPE_DATA (stream, dynarr)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1407
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1408 struct dynarr_stream
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1409 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1410 unsigned_char_dynarr *dyn;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1411 };
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1412
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1413 DEFINE_LSTREAM_IMPLEMENTATION ("dynarr", lstream_dynarr,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1414 sizeof (struct dynarr_stream));
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1415
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1416 Lisp_Object
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1417 make_dynarr_output_stream (unsigned_char_dynarr *dyn)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1418 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1419 Lisp_Object obj;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1420 XSETLSTREAM (obj, Lstream_new (lstream_dynarr, "w"));
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1421 DYNARR_STREAM_DATA (XLSTREAM (obj))->dyn = dyn;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1422 return obj;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1423 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1424
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
1425 static Bytecount
462
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents: 456
diff changeset
1426 dynarr_writer (Lstream *stream, const unsigned char *data,
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
1427 Bytecount size)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1428 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1429 struct dynarr_stream *str = DYNARR_STREAM_DATA (stream);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1430 Dynarr_add_many (str->dyn, data, size);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1431 return size;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1432 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1433
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1434 static int
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1435 dynarr_rewinder (Lstream *stream)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1436 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1437 Dynarr_reset (DYNARR_STREAM_DATA (stream)->dyn);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1438 return 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1439 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1440
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1441 static int
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1442 dynarr_closer (Lstream *stream)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1443 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1444 return 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1445 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1446
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1447 /************ read from or write to a Lisp buffer ************/
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1448
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1449 /* Note: Lisp-buffer read streams never return partial characters,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1450 and Lisp-buffer write streams expect to never get partial
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1451 characters. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1452
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1453 #define LISP_BUFFER_STREAM_DATA(stream) \
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1454 LSTREAM_TYPE_DATA (stream, lisp_buffer)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1455
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1456 struct lisp_buffer_stream
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1457 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1458 Lisp_Object buffer;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1459 Lisp_Object orig_start;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1460 /* we use markers to properly deal with insertion/deletion */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1461 Lisp_Object start, end;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1462 int flags;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1463 };
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1464
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1465 DEFINE_LSTREAM_IMPLEMENTATION ("lisp-buffer", lstream_lisp_buffer,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1466 sizeof (struct lisp_buffer_stream));
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1467
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1468 static Lisp_Object
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
1469 make_lisp_buffer_stream_1 (struct buffer *buf, Charbpos start, Charbpos end,
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
1470 int flags, const char *mode)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1471 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1472 Lisp_Object obj;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1473 Lstream *lstr;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1474 struct lisp_buffer_stream *str;
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
1475 Charbpos bmin, bmax;
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1476 int reading = !strcmp (mode, "r");
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1477
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1478 /* Make sure the luser didn't pass "w" in. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1479 if (!strcmp (mode, "w"))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1480 abort ();
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1481
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1482 if (flags & LSTR_IGNORE_ACCESSIBLE)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1483 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1484 bmin = BUF_BEG (buf);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1485 bmax = BUF_Z (buf);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1486 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1487 else
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1488 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1489 bmin = BUF_BEGV (buf);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1490 bmax = BUF_ZV (buf);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1491 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1492
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1493 if (start == -1)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1494 start = bmin;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1495 if (end == -1)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1496 end = bmax;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1497 assert (bmin <= start);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1498 assert (start <= bmax);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1499 if (reading)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1500 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1501 assert (bmin <= end);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1502 assert (end <= bmax);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1503 assert (start <= end);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1504 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1505
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1506 lstr = Lstream_new (lstream_lisp_buffer, mode);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1507 str = LISP_BUFFER_STREAM_DATA (lstr);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1508 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1509 Lisp_Object marker;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1510 Lisp_Object buffer;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1511
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1512 XSETBUFFER (buffer, buf);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1513 marker = Fmake_marker ();
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1514 Fset_marker (marker, make_int (start), buffer);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1515 str->start = marker;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1516 marker = Fmake_marker ();
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1517 Fset_marker (marker, make_int (start), buffer);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1518 str->orig_start = marker;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1519 if (reading)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1520 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1521 marker = Fmake_marker ();
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1522 Fset_marker (marker, make_int (end), buffer);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1523 str->end = marker;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1524 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1525 else
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1526 str->end = Qnil;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1527 str->buffer = buffer;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1528 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1529 str->flags = flags;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1530 XSETLSTREAM (obj, lstr);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1531 return obj;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1532 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1533
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1534 Lisp_Object
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
1535 make_lisp_buffer_input_stream (struct buffer *buf, Charbpos start, Charbpos end,
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1536 int flags)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1537 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1538 return make_lisp_buffer_stream_1 (buf, start, end, flags, "r");
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1539 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1540
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1541 Lisp_Object
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
1542 make_lisp_buffer_output_stream (struct buffer *buf, Charbpos pos, int flags)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1543 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1544 Lisp_Object lstr = make_lisp_buffer_stream_1 (buf, pos, 0, flags, "wc");
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1545
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1546 Lstream_set_character_mode (XLSTREAM (lstr));
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1547 return lstr;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1548 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1549
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
1550 static Bytecount
462
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents: 456
diff changeset
1551 lisp_buffer_reader (Lstream *stream, unsigned char *data,
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
1552 Bytecount size)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1553 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1554 struct lisp_buffer_stream *str = LISP_BUFFER_STREAM_DATA (stream);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1555 unsigned char *orig_data = data;
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
1556 Bytebpos start;
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
1557 Bytebpos end;
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1558 struct buffer *buf = XBUFFER (str->buffer);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1559
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1560 if (!BUFFER_LIVE_P (buf))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1561 return 0; /* Fut. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1562
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
1563 /* NOTE: We do all our operations in Bytebpos's.
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1564 Keep in mind that SIZE is a value in bytes, not chars. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1565
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1566 start = bi_marker_position (str->start);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1567 end = bi_marker_position (str->end);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1568 if (!(str->flags & LSTR_IGNORE_ACCESSIBLE))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1569 {
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
1570 start = bytebpos_clip_to_bounds (BI_BUF_BEGV (buf), start,
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1571 BI_BUF_ZV (buf));
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
1572 end = bytebpos_clip_to_bounds (BI_BUF_BEGV (buf), end,
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1573 BI_BUF_ZV (buf));
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1574 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1575
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
1576 size = min (size, (Bytecount) (end - start));
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1577 end = start + size;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1578 /* We cannot return a partial character. */
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
1579 VALIDATE_BYTEBPOS_BACKWARD (buf, end);
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1580
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1581 while (start < end)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1582 {
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
1583 Bytebpos ceil;
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1584 Bytecount chunk;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1585
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1586 if (str->flags & LSTR_IGNORE_ACCESSIBLE)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1587 ceil = BI_BUF_CEILING_OF_IGNORE_ACCESSIBLE (buf, start);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1588 else
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1589 ceil = BI_BUF_CEILING_OF (buf, start);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1590 chunk = min (ceil, end) - start;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1591 memcpy (data, BI_BUF_BYTE_ADDRESS (buf, start), chunk);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1592 data += chunk;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1593 start += chunk;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1594 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1595
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1596 if (EQ (buf->selective_display, Qt) && str->flags & LSTR_SELECTIVE)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1597 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1598 /* What a kludge. What a kludge. What a kludge. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1599 unsigned char *p;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1600 for (p = orig_data; p < data; p++)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1601 if (*p == '\r')
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1602 *p = '\n';
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1603 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1604
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1605 set_bi_marker_position (str->start, end);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1606 return data - orig_data;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1607 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1608
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
1609 static Bytecount
462
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents: 456
diff changeset
1610 lisp_buffer_writer (Lstream *stream, const unsigned char *data,
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
1611 Bytecount size)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1612 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1613 struct lisp_buffer_stream *str = LISP_BUFFER_STREAM_DATA (stream);
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
1614 Charbpos pos;
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1615 struct buffer *buf = XBUFFER (str->buffer);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1616
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1617 if (!BUFFER_LIVE_P (buf))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1618 return 0; /* Fut. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1619
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1620 pos = marker_position (str->start);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1621 pos += buffer_insert_raw_string_1 (buf, pos, data, size, 0);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1622 set_marker_position (str->start, pos);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1623 return size;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1624 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1625
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1626 static int
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1627 lisp_buffer_rewinder (Lstream *stream)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1628 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1629 struct lisp_buffer_stream *str =
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1630 LISP_BUFFER_STREAM_DATA (stream);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1631 struct buffer *buf = XBUFFER (str->buffer);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1632 long pos = marker_position (str->orig_start);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1633 if (!BUFFER_LIVE_P (buf))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1634 return -1; /* Fut. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1635 if (pos > BUF_ZV (buf))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1636 pos = BUF_ZV (buf);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1637 if (pos < marker_position (str->orig_start))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1638 pos = marker_position (str->orig_start);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1639 if (MARKERP (str->end) && pos > marker_position (str->end))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1640 pos = marker_position (str->end);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1641 set_marker_position (str->start, pos);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1642 return 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1643 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1644
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1645 static Lisp_Object
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1646 lisp_buffer_marker (Lisp_Object stream)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1647 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1648 struct lisp_buffer_stream *str =
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1649 LISP_BUFFER_STREAM_DATA (XLSTREAM (stream));
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1650
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1651 mark_object (str->start);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1652 mark_object (str->end);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1653 return str->buffer;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1654 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1655
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
1656 Charbpos
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1657 lisp_buffer_stream_startpos (Lstream *stream)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1658 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1659 return marker_position (LISP_BUFFER_STREAM_DATA (stream)->start);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1660 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1661
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1662
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1663 /************************************************************************/
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1664 /* initialization */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1665 /************************************************************************/
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1666
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1667 void
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1668 lstream_type_create (void)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1669 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1670 LSTREAM_HAS_METHOD (stdio, reader);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1671 LSTREAM_HAS_METHOD (stdio, writer);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1672 LSTREAM_HAS_METHOD (stdio, rewinder);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1673 LSTREAM_HAS_METHOD (stdio, seekable_p);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1674 LSTREAM_HAS_METHOD (stdio, flusher);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1675 LSTREAM_HAS_METHOD (stdio, closer);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1676
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1677 LSTREAM_HAS_METHOD (filedesc, reader);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1678 LSTREAM_HAS_METHOD (filedesc, writer);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1679 LSTREAM_HAS_METHOD (filedesc, was_blocked_p);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1680 LSTREAM_HAS_METHOD (filedesc, rewinder);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1681 LSTREAM_HAS_METHOD (filedesc, seekable_p);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1682 LSTREAM_HAS_METHOD (filedesc, closer);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1683
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1684 LSTREAM_HAS_METHOD (lisp_string, reader);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1685 LSTREAM_HAS_METHOD (lisp_string, rewinder);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1686 LSTREAM_HAS_METHOD (lisp_string, marker);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1687
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1688 LSTREAM_HAS_METHOD (fixed_buffer, reader);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1689 LSTREAM_HAS_METHOD (fixed_buffer, writer);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1690 LSTREAM_HAS_METHOD (fixed_buffer, rewinder);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1691
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1692 LSTREAM_HAS_METHOD (resizing_buffer, writer);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1693 LSTREAM_HAS_METHOD (resizing_buffer, rewinder);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1694 LSTREAM_HAS_METHOD (resizing_buffer, closer);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1695
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1696 LSTREAM_HAS_METHOD (dynarr, writer);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1697 LSTREAM_HAS_METHOD (dynarr, rewinder);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1698 LSTREAM_HAS_METHOD (dynarr, closer);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1699
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1700 LSTREAM_HAS_METHOD (lisp_buffer, reader);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1701 LSTREAM_HAS_METHOD (lisp_buffer, writer);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1702 LSTREAM_HAS_METHOD (lisp_buffer, rewinder);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1703 LSTREAM_HAS_METHOD (lisp_buffer, marker);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1704 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1705
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1706 void
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1707 reinit_vars_of_lstream (void)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1708 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1709 int i;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1710
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1711 for (i = 0; i < countof (Vlstream_free_list); i++)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1712 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1713 Vlstream_free_list[i] = Qnil;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1714 staticpro_nodump (&Vlstream_free_list[i]);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1715 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1716 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1717
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1718 void
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1719 vars_of_lstream (void)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1720 {
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
1721 INIT_LRECORD_IMPLEMENTATION (lstream);
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
1722
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1723 reinit_vars_of_lstream ();
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1724 }