annotate src/lstream.c @ 1296:87084e8445a7

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