annotate src/lstream.c @ 872:79c6ff3eef26

[xemacs-hg @ 2002-06-20 21:18:01 by ben] font changes etc.; some 21.4 changes mule/mule-msw-init-late.el: Specify charset->windows-registry conversion. mule/mule-x-init.el: Delete extra mule font additions here. Put them in faces.c. cl-macs.el: Document better. font-lock.el: Move Lisp function regexp to lisp-mode.el. lisp-mode.el: Various indentation fixes: Handle flet functions better. Handle argument lists in defuns and flets. Handle quoted lists, e.g. property lists -- don't indent like function calls. Distinguish between lambdas and other lists. lisp-mode.el: Handle this form. faces.el, font-menu.el, font.el, gtk-faces.el, msw-faces.el, msw-font-menu.el, x-faces.el, x-init.el: Major overhaul of face-handling code: -- Fix lots of bogus code in msw-faces.el, msw-font-menu.el, font-menu.el that was "truenaming" font specs -- i.e. in the process of frobbing a particular field in a general user-specified font spec with wildcarded fields, sticking in particular values for all the remaining wildcarded fields. This bug was rampant everywhere except in x-faces.el (the oldest and only correctly written code). This also means that we need to work with font names at all times and not font instances, because a font instance is essentially a truenamed font. -- Total rewrite of extremely junky code in msw-faces.el. Work with names as well as font instances, and return names; stop truenaming when canonicalizing and frobbing; fix handling of the combined style field, i.e. weight/slant (also fixed in font.el). -- Totally rewrite the frobbing functions in faces.el. This time, we frob all the instantiators rather than just computing a single instance value and working backwards. That way, e.g., `bold' will work for all charsets that have bold available, rather than only for whatever charset was part of the computed font instance (another example of the truename virus). Also fix up code to look at the fallbacks (all of them) when no global value present, so we don't need to put something in the global value. Intelligently handle a request to frob a buffer locale, rather than signalling an error. When frobbing instantiators, try hard to figure out what device type is associated with them, and frob each according to its own proper device type. Correctly handle inheritance vectors given as instantiators. Preserve existing tags when putting back frobbed instantiators. Extract out general specifier-frobbing code into specifier.el. Document everything cleanly. Do lots of other things better, etc. -- Don't duplicatively set a global specification for the default font -- it's already in the fallback and we no longer need a default global specification present. Delete various code in x-faces.el and msw-faces.el that duplicated the lists of fonts in faces.c. -- init-global-faces was not being called at all under MS Windows! Major bogosity. That caused device-specific values to get stuck into all the fonts, making it very hard to change them -- setting global specs caused nothing to happen. -- Correct weight names in font.el. -- Lots more font fixups in objects*.c. Printer.el: Warning fix. specifier.el: Add more args to map-specifier. Add various "heuristic" specifier functions to aid in creation of specifier-munging code such as in faces.el. subr.el: New functions. lwlib.c: Fix warning. config.inc.samp: Clean up, add args to control fastcall (not yet supported! the changes needed are in another ws of mine), profile support, vc6 support, union-type. xemacs.dsp, xemacs.mak: Semi-major overhaul. Fix bug where dump-id was always getting recomputed, forcing a redump even when nothing changed. Add support for fastcall. Support edit-and-continue (on by default) with vc6. Use incremental linking when doing a debug compilation. Add support for profiling. Consolidate the various debug flags. Partial support for "batch-compiling" -- compiling many files on a single invocation of the compiler. Doesn't seem to help that much for me, so it's not finished or enabled by default. Remove HAVE_MSW_C_DIRED, we always do. Correct some sloppy use of directories. s/cygwin32.h: Allow pdump to work under Cygwin (mmap is broken, so need to undefine HAVE_MMAP). s/win32-common.h, s/windowsnt.h: Support for fastcall. Add WIN32_ANY for identifying all Win32 variants (Cygwin, native, MinGW). Both of these are properly used in another ws. alloc.c, balloon-x.c, buffer.c, bytecode.c, callint.c, cm.c, cmdloop.c, cmds.c, console-gtk.c, console-gtk.h, console-msw.c, console-msw.h, console-stream.c, console-stream.h, console-tty.c, console-tty.h, console-x.c, console-x.h, console.c, console.h, device-gtk.c, device-msw.c, device-tty.c, device-x.c, device.c, device.h, devslots.h, dialog-gtk.c, dialog-msw.c, dialog-x.c, dialog.c, dired-msw.c, editfns.c, emacs.c, event-Xt.c, event-gtk.c, event-msw.c, event-stream.c, event-tty.c, event-unixoid.c, events.c, extents.c, extents.h, faces.c, fileio.c, fns.c, frame-gtk.c, frame-msw.c, frame-tty.c, frame-x.c, frame.c, frame.h, glyphs-eimage.c, glyphs-gtk.c, glyphs-msw.c, glyphs-widget.c, glyphs-x.c, glyphs.c, glyphs.h, gui-gtk.c, gui-msw.c, gui-x.c, gui.c, gutter.c, input-method-xlib.c, intl-encap-win32.c, intl-win32.c, keymap.c, lisp.h, macros.c, menubar-gtk.c, menubar-msw.c, menubar-x.c, menubar.c, menubar.h, minibuf.c, mule-charset.c, nt.c, objects-gtk.c, objects-gtk.h, objects-msw.c, objects-msw.h, objects-tty.c, objects-tty.h, objects-x.c, objects-x.h, objects.c, objects.h, postgresql.c, print.c, process.h, redisplay-gtk.c, redisplay-msw.c, redisplay-output.c, redisplay-tty.c, redisplay-x.c, redisplay.c, redisplay.h, scrollbar-gtk.c, scrollbar-msw.c, scrollbar-x.c, scrollbar.c, select-gtk.c, select-msw.c, select-x.c, select.c, signal.c, sound.c, specifier.c, symbols.c, syntax.c, sysdep.c, syssignal.h, syswindows.h, toolbar-common.c, toolbar-gtk.c, toolbar-msw.c, toolbar-x.c, toolbar.c, unicode.c, window.c, window.h: The following are the major changes made: (1) Separation of various header files into an external and an internal version, similar to the existing separation of process.h and procimpl.h. Eventually this should be done for all Lisp objects. The external version has the same name as currently; the internal adds -impl. The external file has XFOO() macros for objects, but the structure is opaque and defined only in the internal file. It's now reasonable to move all prototypes in lisp.h into the appropriate external file, and this should be done. Currently, separation has been done on extents.h, objects*.h, console.h, device.h, frame.h, and window.h. For c/d/f/w, the most basic properties are available in the external header file, with the macros resolving to functions. In the internal header file, the macros are redefined to directly access the structure. Also, the global MARK_FOO_CHANGED macros have been made into functions so that they can be accessed without needing to include lots of -impl headers -- they are used in almost exclusively in non-time-critical functions, and take up enough time that the function overhead will be negligible. Similarly, the function overhead from making the basic properties mentioned above into functions is negligible, and code that does heavy accessing of c/d/f/w structures inevitably ends up needing the internal header files, anyway. (2) More face changes. -- Major rewrite of objects-msw.c. Now handles wildcard specs properly, rather than "truenaming" (or even worse, signalling an error, which previously happened with some of the fallbacks if you tried to use them in make-font-instance!). -- Split charset matching of fonts into two stages -- one to find a font specifically designed for a particular charset (by examining its registry), the second to find a Unicode font that can support the charset. This needs to proceed as two complete, separate instantiations in order to work properly (otherwise many of the fonts in the HELLO page look wrong). This should also make it easy to support iso10646 (Unicode) fonts under X. -- All default values for fonts are now completely specified in the fallbacks. Stuff from mule-x-init.el has all been moved here, merged with the existing specs, and totally rethought so you get sensible results. (HELLO now looks much better!). -- Generalize the "default X/GTK device" stuff into a per-device-type "default device". -- Add mswindows-{set-}charset-registry. In time, charset<->code-page conversion functions will be removed. -- Wrap protective code around calls to compute device specifier tags, and do this computation before calling the face initialization code because the latter may need these tags to be correctly updated. (3) Other changes. EmacsFrame.c, glyphs-msw.c, eval.c, gui-x.c, intl-encap-win32.c, search.c, signal.c, toolbar-msw.c, unicode.c: Warning fixes. config.h.in: #undefs meant to be frobbed by configure *MUST* go inside of #ifndef WIN32_NO_CONFIGURE, and everything else *MUST* go outside! eval.c: Let detailed backtraces be detailed. specifier.c: Don't override user's print-string-length/print-length settings. glyphs.c: New function image-instance-instantiator. config.h.in, sysdep.c: Changes for fastcall. sysdep.c, nt.c: Fix up a previous botched patch that tried to add support for both EEXIST and EACCES. IF THE BOTCHED PATCH WENT INTO 21.4, THIS FIXUP NEEDS TO GO IN, TOO. search.c: Fix *evil* crash due to incorrect synching of syntax-cache code with 21.1. THIS SHOULD GO INTO 21.4.
author ben
date Thu, 20 Jun 2002 21:19:10 +0000
parents 804517e16990
children c925bacdda60
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
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
117 DEFINE_LRECORD_SEQUENCE_IMPLEMENTATION ("stream", lstream,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
118 mark_lstream, print_lstream,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
119 finalize_lstream, 0, 0, 0,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
120 sizeof_lstream, Lstream);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
121
771
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
122
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
123 /* 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
124 buffering is STREAM_BLOCK_BUFFERED. */
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
125
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
126 void
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
127 Lstream_set_buffering (Lstream *lstr, Lstream_buffering buffering,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
128 int buffering_size)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
129 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
130 lstr->buffering = buffering;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
131 switch (buffering)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
132 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
133 case LSTREAM_UNBUFFERED:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
134 lstr->buffering_size = 0; break;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
135 case LSTREAM_BLOCK_BUFFERED:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
136 lstr->buffering_size = DEFAULT_BLOCK_BUFFERING_SIZE; break;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
137 case LSTREAM_BLOCKN_BUFFERED:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
138 lstr->buffering_size = buffering_size; break;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
139 case LSTREAM_LINE_BUFFERED:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
140 case LSTREAM_UNLIMITED:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
141 lstr->buffering_size = INT_MAX; break;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
142 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
143 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
144
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
145 static const Lstream_implementation *lstream_types[32];
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
146 static Lisp_Object Vlstream_free_list[32];
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
147 static int lstream_type_count;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
148
771
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
149 /* 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
150 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
151 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
152 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
153 file). */
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
154
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
155 Lstream *
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
156 Lstream_new (const Lstream_implementation *imp, const char *mode)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
157 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
158 Lstream *p;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
159 int i;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
160
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
161 for (i = 0; i < lstream_type_count; i++)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
162 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
163 if (lstream_types[i] == imp)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
164 break;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
165 }
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 if (i == lstream_type_count)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
168 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
169 assert (lstream_type_count < countof (lstream_types));
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
170 lstream_types[lstream_type_count] = imp;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
171 Vlstream_free_list[lstream_type_count] =
456
e7ef97881643 Import from CVS: tag r21-2-43
cvs
parents: 444
diff changeset
172 make_lcrecord_list (aligned_sizeof_lstream (imp->size),
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
173 &lrecord_lstream);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
174 lstream_type_count++;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
175 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
176
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
177 p = XLSTREAM (allocate_managed_lcrecord (Vlstream_free_list[i]));
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
178 /* Zero it out, except the header. */
456
e7ef97881643 Import from CVS: tag r21-2-43
cvs
parents: 444
diff changeset
179 memset ((char *) p + sizeof (p->header), '\0',
e7ef97881643 Import from CVS: tag r21-2-43
cvs
parents: 444
diff changeset
180 aligned_sizeof_lstream (imp->size) - sizeof (p->header));
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
181 p->imp = imp;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
182 Lstream_set_buffering (p, LSTREAM_BLOCK_BUFFERED, 0);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
183 p->flags = LSTREAM_FL_IS_OPEN;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
184
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
185 /* convert mode (one of "r", "w", "rc", "wc") to p->flags */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
186 assert (mode[0] == 'r' || mode[0] == 'w');
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
187 assert (mode[1] == 'c' || mode[1] == '\0');
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
188 p->flags |= (mode[0] == 'r' ? LSTREAM_FL_READ : LSTREAM_FL_WRITE);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
189 if (mode[1] == 'c')
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
190 p->flags |= LSTREAM_FL_NO_PARTIAL_CHARS;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
191
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
192 return p;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
193 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
194
771
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
195 /* 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
196 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
197 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
198 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
199 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
200 end and the stream is implemented correctly.)
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
201
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
202 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
203 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
204 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
205 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
206 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
207 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
208 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
209 *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
210 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
211 time.
a634e3b7acc8 [xemacs-hg @ 2002-04-14 12:41:59 by ben]
ben
parents: 800
diff changeset
212
a634e3b7acc8 [xemacs-hg @ 2002-04-14 12:41:59 by ben]
ben
parents: 800
diff changeset
213 (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
214 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
215 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
216 creation time to disable this behavior.) */
771
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
217
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
218 void
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
219 Lstream_set_character_mode (Lstream *lstr)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
220 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
221 lstr->flags |= LSTREAM_FL_NO_PARTIAL_CHARS;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
222 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
223
771
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
224 /* Unset character mode. See Lstream_set_character_mode(). */
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
225
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
226 void
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
227 Lstream_unset_character_mode (Lstream *lstr)
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
228 {
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
229 lstr->flags &= ~LSTREAM_FL_NO_PARTIAL_CHARS;
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
230 }
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
231
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
232 /* 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
233 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
234 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
235 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
236 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
237 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
238 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
239 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
240 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
241 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
242 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
243 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
244 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
245 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
246
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
247 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
248 will be aborted. See free_managed_lcrecord(). */
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
249
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
250 void
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
251 Lstream_delete (Lstream *lstr)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
252 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
253 int i;
793
e38acbeb1cae [xemacs-hg @ 2002-03-29 04:46:17 by ben]
ben
parents: 788
diff changeset
254 Lisp_Object val = wrap_lstream (lstr);
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
255
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
256 for (i = 0; i < lstream_type_count; i++)
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 if (lstream_types[i] == lstr->imp)
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 free_managed_lcrecord (Vlstream_free_list[i], val);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
261 return;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
262 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
263 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
264
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
265 abort ();
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
266 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
267
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
268 #define Lstream_internal_error(reason, lstr) \
563
183866b06e0b [xemacs-hg @ 2001-05-24 07:50:48 by ben]
ben
parents: 462
diff changeset
269 signal_error (Qinternal_error, reason, wrap_lstream (lstr))
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
270
771
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
271 /* 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
272 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
273 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
274 necessary storage structures, for example. */
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
275
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
276 void
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
277 Lstream_reopen (Lstream *lstr)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
278 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
279 if (lstr->flags & LSTREAM_FL_IS_OPEN)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
280 Lstream_internal_error ("lstream already open", lstr);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
281 lstr->flags |= LSTREAM_FL_IS_OPEN;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
282 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
283
771
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
284 /* 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
285 number of bytes written. */
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
286
771
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
287 static int
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
288 Lstream_really_write (Lstream *lstr, const unsigned char *data, int size)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
289 {
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
290 Bytecount num_written;
771
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
291 const unsigned char *orig_data = data;
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
292 int error_occurred = 0;
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
293
771
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
294 while (size > 0)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
295 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
296 if (! (lstr->flags & LSTREAM_FL_IS_OPEN))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
297 Lstream_internal_error ("lstream not open", lstr);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
298 if (! (lstr->flags & LSTREAM_FL_WRITE))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
299 Lstream_internal_error ("lstream not open for writing", lstr);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
300 if (!lstr->imp->writer)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
301 Lstream_internal_error ("lstream has no writer", lstr);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
302
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
303 if (lstr->flags & LSTREAM_FL_NO_PARTIAL_CHARS)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
304 /* It's quite possible for us to get passed an incomplete
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
305 character at the end. We need to spit back that
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
306 incomplete character. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
307 {
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
308 const unsigned char *dataend = data + size - 1;
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
309 assert (size > 0); /* safety check ... */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
310 /* Optimize the most common case. */
826
6728e641994e [xemacs-hg @ 2002-05-05 11:30:15 by ben]
ben
parents: 814
diff changeset
311 if (!byte_ascii_p (*dataend))
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
312 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
313 /* Go back to the beginning of the last (and possibly partial)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
314 character, and bump forward to see if the character is
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
315 complete. */
867
804517e16990 [xemacs-hg @ 2002-06-05 09:54:39 by ben]
ben
parents: 840
diff changeset
316 VALIDATE_IBYTEPTR_BACKWARD (dataend);
826
6728e641994e [xemacs-hg @ 2002-05-05 11:30:15 by ben]
ben
parents: 814
diff changeset
317 if (dataend + rep_bytes_by_first_byte (*dataend) != data + size)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
318 /* If not, chop the size down to ignore the last char
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
319 and stash it away for next time. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
320 size = dataend - data;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
321 /* If we don't even have one character to write, then just
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
322 skip out. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
323 if (size == 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
324 break;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
325 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
326 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
327
771
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
328 num_written = (lstr->imp->writer) (lstr, data, size);
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
329 if (num_written == 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
330 /* If nothing got written, then just hold the data. This may
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
331 occur, for example, if this stream does non-blocking I/O;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
332 the attempt to write the data might have resulted in an
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
333 EWOULDBLOCK error. */
771
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
334 break;
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
335 else if (num_written > size)
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
336 abort ();
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
337 else if (num_written > 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
338 {
771
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
339 data += num_written;
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
340 size -= num_written;
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
341 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
342 else
771
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
343 {
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
344 /* 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
345 error_occurred = 1;
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
346 break;
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
347 }
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
348 }
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 if (lstr->imp->flusher)
771
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
351 error_occurred = (lstr->imp->flusher) (lstr) < 0;
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
352
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
353 if (data == orig_data && error_occurred)
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
354 return -1;
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
355
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
356 return data - orig_data;
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
357 }
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
358
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
359 /* 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
360 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
361 nothing written and error occurred, 0 otherwise. */
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
362
771
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
363 int
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
364 Lstream_flush_out (Lstream *lstr)
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
365 {
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
366 Bytecount num_written =
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
367 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
368 if (num_written == lstr->out_buffer_ind)
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
369 {
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
370 lstr->out_buffer_ind = 0;
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
371 return 0;
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
372 }
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
373 else if (num_written > 0)
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
374 {
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
375 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
376 lstr->out_buffer_ind - num_written);
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
377 lstr->out_buffer_ind -= num_written;
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
378 return 0;
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
379 }
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
380 else return num_written;
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
381 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
382
771
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
383 /* 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
384 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
385 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
386 error. */
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
387
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
388 int
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
389 Lstream_flush (Lstream *lstr)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
390 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
391 if (Lstream_flush_out (lstr) < 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
392 return -1;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
393
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
394 /* clear out buffered data */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
395 lstr->in_buffer_current = lstr->in_buffer_ind = 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
396 lstr->unget_buffer_ind = 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
397
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
398 return 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
399 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
400
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
401 /* We want to add NUM characters. This function ensures that the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
402 buffer is large enough for this (per the buffering size specified
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
403 in the stream) and returns the number of characters we can
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
404 actually write. If FORCE is set, ignore the buffering size
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
405 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
406 the buffering size. (This is used to deal with the possibility
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
407 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
408 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
409 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
410
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
411 static Bytecount
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
412 Lstream_adding (Lstream *lstr, Bytecount num, int force)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
413 {
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
414 Bytecount size = num + lstr->out_buffer_ind;
430
a5df635868b2 Import from CVS: tag r21-2-23
cvs
parents: 428
diff changeset
415
a5df635868b2 Import from CVS: tag r21-2-23
cvs
parents: 428
diff changeset
416 if (size <= lstr->out_buffer_size)
a5df635868b2 Import from CVS: tag r21-2-23
cvs
parents: 428
diff changeset
417 return num;
a5df635868b2 Import from CVS: tag r21-2-23
cvs
parents: 428
diff changeset
418
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
419 /* Maybe chop it down so that we don't buffer more characters
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
420 than our advertised buffering size. */
430
a5df635868b2 Import from CVS: tag r21-2-23
cvs
parents: 428
diff changeset
421 if ((size > lstr->buffering_size) && !force)
a5df635868b2 Import from CVS: tag r21-2-23
cvs
parents: 428
diff changeset
422 {
a5df635868b2 Import from CVS: tag r21-2-23
cvs
parents: 428
diff changeset
423 size = lstr->buffering_size;
a5df635868b2 Import from CVS: tag r21-2-23
cvs
parents: 428
diff changeset
424 /* There might be more data buffered than the buffering size. */
a5df635868b2 Import from CVS: tag r21-2-23
cvs
parents: 428
diff changeset
425 if (size <= lstr->out_buffer_ind)
a5df635868b2 Import from CVS: tag r21-2-23
cvs
parents: 428
diff changeset
426 return 0;
a5df635868b2 Import from CVS: tag r21-2-23
cvs
parents: 428
diff changeset
427 }
a5df635868b2 Import from CVS: tag r21-2-23
cvs
parents: 428
diff changeset
428
a5df635868b2 Import from CVS: tag r21-2-23
cvs
parents: 428
diff changeset
429 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
430
a5df635868b2 Import from CVS: tag r21-2-23
cvs
parents: 428
diff changeset
431 return size - lstr->out_buffer_ind;
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
432 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
433
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
434 /* Like Lstream_write(), but does not handle line-buffering correctly. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
435
771
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
436 static int
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
437 Lstream_write_1 (Lstream *lstr, const void *data, Bytecount size)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
438 {
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
439 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
440 Bytecount off = 0;
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
441 if (! (lstr->flags & LSTREAM_FL_IS_OPEN))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
442 Lstream_internal_error ("lstream not open", lstr);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
443 if (! (lstr->flags & LSTREAM_FL_WRITE))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
444 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
445
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
446 if (lstr->buffering == LSTREAM_UNBUFFERED)
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
447 {
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
448 /* 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
449 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
450 data. Try to write it now. */
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
451 if (lstr->out_buffer_ind > 0)
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
452 {
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
453 if (Lstream_flush_out (lstr) < 0)
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
454 return -1;
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
455 }
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
456
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
457 /* 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
458 if (lstr->out_buffer_ind == 0)
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
459 {
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
460 /* 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
461 for us. */
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
462 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
463 if (num_written < 0)
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
464 return -1;
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
465 off += num_written;
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
466 }
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
467
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
468 /* squirrel away the rest of the data */
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
469 if (off < size)
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
470 {
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
471 Lstream_adding (lstr, size - off, 1);
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
472 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
473 size - off);
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
474 lstr->out_buffer_ind += size - off;
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
475 }
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
476
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
477 lstr->byte_count += size;
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
478 return 0;
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
479 }
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
480 else
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
481 {
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
482 int couldnt_write_last_time = 0;
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
483
771
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
484 while (1)
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
485 {
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
486 /* 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
487 Bytecount chunk = Lstream_adding (lstr, size, 0);
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
488 if (chunk == 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 (couldnt_write_last_time)
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
491 /* 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
492 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
493 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
494 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
495 stuff. */
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
496 chunk = Lstream_adding (lstr, size, 1);
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
497 else
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
498 couldnt_write_last_time = 1;
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
499 }
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
500 /* Do it. */
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
501 if (chunk > 0)
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
502 {
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
503 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
504 lstr->out_buffer_ind += chunk;
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
505 lstr->byte_count += chunk;
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
506 size -= chunk;
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
507 off += chunk;
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
508 }
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
509 /* 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
510 if (size > 0)
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
511 {
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
512 if (Lstream_flush_out (lstr) < 0)
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 if (off == 0)
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
515 return -1;
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
516 else
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
517 return 0;
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 }
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
520 else
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
521 break;
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 }
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
524 return 0;
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
525 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
526
771
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
527 /* 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
528 -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
529 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
530 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
531 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
532 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
533 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
534 way to control whether this happens.) */
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
535
771
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
536 int
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
537 Lstream_write (Lstream *lstr, const void *data, Bytecount size)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
538 {
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
539 Bytecount i;
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
540 const unsigned char *p = (const unsigned char *) data;
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
541
771
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
542 /* 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
543 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
544 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
545 Returns 0 on success, -1 on failure. */
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
546
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
547 if (size == 0)
771
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
548 return 0;
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
549 if (lstr->buffering != LSTREAM_LINE_BUFFERED)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
550 return Lstream_write_1 (lstr, data, size);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
551 for (i = 0; i < size; i++)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
552 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
553 if (Lstream_putc (lstr, p[i]) < 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
554 break;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
555 }
771
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
556 return i == 0 ? -1 : 0;
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
557 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
558
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
559 int
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
560 Lstream_was_blocked_p (Lstream *lstr)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
561 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
562 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
563 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
564
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
565 static Bytecount
462
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents: 456
diff changeset
566 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
567 Bytecount size)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
568 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
569 if (! (lstr->flags & LSTREAM_FL_IS_OPEN))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
570 Lstream_internal_error ("lstream not open", lstr);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
571 if (! (lstr->flags & LSTREAM_FL_READ))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
572 Lstream_internal_error ("lstream not open for reading", lstr);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
573 if (!lstr->imp->reader)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
574 Lstream_internal_error ("lstream has no reader", lstr);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
575
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
576 return (lstr->imp->reader) (lstr, buffer, size);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
577 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
578
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
579 /* Assuming the buffer is empty, fill it up again. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
580
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
581 static Bytecount
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
582 Lstream_read_more (Lstream *lstr)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
583 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
584 #if 0
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
585 Bytecount size_needed
462
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents: 456
diff changeset
586 = max (1, min (MAX_READ_SIZE, lstr->buffering_size));
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
587 #else
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
588 /* 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
589 Bytecount size_needed =
462
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents: 456
diff changeset
590 max (1, lstr->buffering_size);
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
591 #endif
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
592 Bytecount size_gotten;
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
593
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
594 DO_REALLOC (lstr->in_buffer, lstr->in_buffer_size,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
595 size_needed, unsigned char);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
596 size_gotten = Lstream_raw_read (lstr, lstr->in_buffer, size_needed);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
597 lstr->in_buffer_current = max (0, size_gotten);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
598 lstr->in_buffer_ind = 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
599 return size_gotten < 0 ? -1 : size_gotten;
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
771
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
602 /* 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
603 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
604 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
605 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
606
814
a634e3b7acc8 [xemacs-hg @ 2002-04-14 12:41:59 by ben]
ben
parents: 800
diff changeset
607 static Bytecount
a634e3b7acc8 [xemacs-hg @ 2002-04-14 12:41:59 by ben]
ben
parents: 800
diff changeset
608 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
609 int override_no_partial_chars)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
610 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
611 unsigned char *p = (unsigned char *) data;
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
612 Bytecount off = 0;
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
613 Bytecount chunk;
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
614 int error_occurred = 0;
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 if (size == 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
617 return 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
618
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
619 /* First try to get some data from the unget buffer */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
620 chunk = min (size, lstr->unget_buffer_ind);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
621 if (chunk > 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
622 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
623 /* The bytes come back in reverse order. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
624 for (; off < chunk; off++)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
625 p[off] = lstr->unget_buffer[--lstr->unget_buffer_ind];
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
626 lstr->byte_count += chunk;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
627 size -= chunk;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
628 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
629
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
630 while (size > 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
631 {
771
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
632 /* 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
633 No need to copy. */
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
634 if (lstr->buffering == LSTREAM_UNBUFFERED)
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
635 {
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
636 chunk = Lstream_raw_read (lstr, p + off, size);
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
637 if (chunk < 0)
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
638 error_occurred = 1;
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
639 if (chunk <= 0)
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
640 break;
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
641 lstr->byte_count += chunk;
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
642 size -= chunk;
771
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
643 off += chunk;
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
644 }
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
645 else
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
646 {
771
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
647 /* Take whatever we can from the in buffer */
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
648 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
649 if (chunk > 0)
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
650 {
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
651 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
652 lstr->in_buffer_ind += chunk;
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
653 lstr->byte_count += chunk;
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
654 size -= chunk;
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
655 off += chunk;
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
656 }
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
657
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
658 /* 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
659 stream's end */
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
660 if (size > 0)
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
661 {
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
662 Bytecount retval = Lstream_read_more (lstr);
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
663 if (retval < 0)
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
664 error_occurred = 1;
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
665 if (retval <= 0)
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
666 break;
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
667 }
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
668 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
669 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
670
814
a634e3b7acc8 [xemacs-hg @ 2002-04-14 12:41:59 by ben]
ben
parents: 800
diff changeset
671 if ((lstr->flags & LSTREAM_FL_NO_PARTIAL_CHARS) &&
a634e3b7acc8 [xemacs-hg @ 2002-04-14 12:41:59 by ben]
ben
parents: 800
diff changeset
672 !override_no_partial_chars)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
673 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
674 /* It's quite possible for us to get passed an incomplete
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
675 character at the end. We need to spit back that
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
676 incomplete character. */
867
804517e16990 [xemacs-hg @ 2002-06-05 09:54:39 by ben]
ben
parents: 840
diff changeset
677 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
678 if (newoff < off)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
679 {
771
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
680 Lstream_unread (lstr, p + newoff, off - newoff);
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
681 off = newoff;
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
682 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
683 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
684
462
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents: 456
diff changeset
685 return off == 0 && error_occurred ? -1 : off;
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
686 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
687
814
a634e3b7acc8 [xemacs-hg @ 2002-04-14 12:41:59 by ben]
ben
parents: 800
diff changeset
688 Bytecount
a634e3b7acc8 [xemacs-hg @ 2002-04-14 12:41:59 by ben]
ben
parents: 800
diff changeset
689 Lstream_read (Lstream *lstr, void *data, Bytecount size)
a634e3b7acc8 [xemacs-hg @ 2002-04-14 12:41:59 by ben]
ben
parents: 800
diff changeset
690 {
a634e3b7acc8 [xemacs-hg @ 2002-04-14 12:41:59 by ben]
ben
parents: 800
diff changeset
691 return Lstream_read_1 (lstr, data, size, 0);
a634e3b7acc8 [xemacs-hg @ 2002-04-14 12:41:59 by ben]
ben
parents: 800
diff changeset
692 }
a634e3b7acc8 [xemacs-hg @ 2002-04-14 12:41:59 by ben]
ben
parents: 800
diff changeset
693
a634e3b7acc8 [xemacs-hg @ 2002-04-14 12:41:59 by ben]
ben
parents: 800
diff changeset
694
771
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
695 /* 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
696 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
697 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
698 unread data. */
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
699
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
700 void
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
701 Lstream_unread (Lstream *lstr, const void *data, Bytecount size)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
702 {
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
703 const unsigned char *p = (const unsigned char *) data;
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
704
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
705 /* Make sure buffer is big enough */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
706 DO_REALLOC (lstr->unget_buffer, lstr->unget_buffer_size,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
707 lstr->unget_buffer_ind + size, unsigned char);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
708
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
709 lstr->byte_count -= size;
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 /* Bytes have to go on in reverse order -- they are reversed
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
712 again when read back. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
713 while (size--)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
714 lstr->unget_buffer[lstr->unget_buffer_ind++] = p[size];
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
715 }
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 /* Rewind the stream to the beginning. */
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
718
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
719 int
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
720 Lstream_rewind (Lstream *lstr)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
721 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
722 if (!lstr->imp->rewinder)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
723 Lstream_internal_error ("lstream has no rewinder", lstr);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
724 if (Lstream_flush (lstr) < 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
725 return -1;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
726 lstr->byte_count = 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
727 return (lstr->imp->rewinder) (lstr);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
728 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
729
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
730 int
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
731 Lstream_seekable_p (Lstream *lstr)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
732 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
733 if (!lstr->imp->rewinder)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
734 return 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
735 if (!lstr->imp->seekable_p)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
736 return 1;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
737 return (lstr->imp->seekable_p) (lstr);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
738 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
739
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
740 static int
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
741 Lstream_pseudo_close (Lstream *lstr)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
742 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
743 if (!lstr->flags & LSTREAM_FL_IS_OPEN)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
744 Lstream_internal_error ("lstream is not open", lstr);
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 /* don't check errors here -- best not to risk file descriptor loss */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
747 return Lstream_flush (lstr);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
748 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
749
771
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
750 /* 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
751 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
752 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
753 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
754 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
755 out when the file is closed. */
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
756
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
757 int
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
758 Lstream_close (Lstream *lstr)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
759 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
760 int rc = 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
761
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
762 if (lstr->flags & LSTREAM_FL_IS_OPEN)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
763 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
764 rc = Lstream_pseudo_close (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 * We used to return immediately if the closer method reported
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
767 * failure, leaving the stream open. But this is no good, for
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
768 * the following reasons.
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 * 1. The finalizer method used in GC makes no provision for
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
771 * failure, so we must not return without freeing buffer
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
772 * memory.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
773 *
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
774 * 2. The closer method may have already freed some memory
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
775 * used for I/O in this stream. E.g. encoding_closer frees
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
776 * ENCODING_STREAM_DATA(stream)->runoff. If a writer method
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
777 * tries to use this buffer later, it will write into memory
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
778 * that may have been allocated elsewhere. Sometime later
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
779 * you will see a sign that says "Welcome to Crash City."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
780 *
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
781 * 3. The closer can report failure if a flush fails in the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
782 * other stream in a MULE encoding/decoding stream pair.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
783 * The other stream in the pair is closed, but returning
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
784 * early leaves the current stream open. If we try to
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
785 * flush the current stream later, we will crash when the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
786 * flusher notices that the other end stream is closed.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
787 *
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
788 * So, we no longer abort the close if the closer method
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
789 * reports some kind of failure. We still report the failure
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
790 * to the caller.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
791 */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
792 if (lstr->imp->closer)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
793 if ((lstr->imp->closer) (lstr) < 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
794 rc = -1;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
795 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
796
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
797 lstr->flags &= ~LSTREAM_FL_IS_OPEN;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
798 lstr->byte_count = 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
799 /* Note that Lstream_flush() reset all the buffer indices. That way,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
800 the next call to Lstream_putc(), Lstream_getc(), or Lstream_ungetc()
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
801 on a closed stream will call into the function equivalents, which will
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
802 cause an error. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
803
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
804 /* 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
805 is called more than once on the same object */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
806 if (lstr->out_buffer)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
807 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
808 xfree (lstr->out_buffer);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
809 lstr->out_buffer = 0;
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 if (lstr->in_buffer)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
812 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
813 xfree (lstr->in_buffer);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
814 lstr->in_buffer = 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
815 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
816 if (lstr->unget_buffer)
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 xfree (lstr->unget_buffer);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
819 lstr->unget_buffer = 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
820 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
821
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
822 return rc;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
823 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
824
771
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
825
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
826 /* Function equivalent of Lstream_putc(). */
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
827
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
828 int
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
829 Lstream_fputc (Lstream *lstr, int c)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
830 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
831 unsigned char ch = (unsigned char) c;
771
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
832 int retval = Lstream_write_1 (lstr, &ch, 1);
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
833 if (retval == 0 && lstr->buffering == LSTREAM_LINE_BUFFERED && ch == '\n')
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
834 return Lstream_flush_out (lstr);
771
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
835 return retval;
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
836 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
837
771
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
838 /* Function equivalent of Lstream_getc(). */
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
839
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
840 int
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
841 Lstream_fgetc (Lstream *lstr)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
842 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
843 unsigned char ch;
814
a634e3b7acc8 [xemacs-hg @ 2002-04-14 12:41:59 by ben]
ben
parents: 800
diff changeset
844 if (Lstream_read_1 (lstr, &ch, 1, 1) <= 0)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
845 return -1;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
846 return ch;
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
771
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
849 /* Function equivalent of Lstream_ungetc(). */
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
850
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
851 void
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
852 Lstream_fungetc (Lstream *lstr, int c)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
853 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
854 unsigned char ch = (unsigned char) c;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
855 Lstream_unread (lstr, &ch, 1);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
856 }
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 /************************ some stream implementations *********************/
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 /*********** a stdio stream ***********/
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
862
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
863 struct stdio_stream
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
864 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
865 FILE *file;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
866 int closing;
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
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
869 #define STDIO_STREAM_DATA(stream) LSTREAM_TYPE_DATA (stream, stdio)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
870
771
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
871 DEFINE_LSTREAM_IMPLEMENTATION ("stdio", stdio);
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
872
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
873 static Lisp_Object
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
874 make_stdio_stream_1 (FILE *stream, int flags, const char *mode)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
875 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
876 Lstream *lstr = Lstream_new (lstream_stdio, mode);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
877 struct stdio_stream *str = STDIO_STREAM_DATA (lstr);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
878 str->file = stream;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
879 str->closing = flags & LSTR_CLOSING;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
880 lstr->flags |= LSTREAM_FL_CLOSE_AT_DISKSAVE;
793
e38acbeb1cae [xemacs-hg @ 2002-03-29 04:46:17 by ben]
ben
parents: 788
diff changeset
881 return wrap_lstream (lstr);
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
882 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
883
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
884 Lisp_Object
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
885 make_stdio_input_stream (FILE *stream, int flags)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
886 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
887 return make_stdio_stream_1 (stream, flags, "r");
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
888 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
889
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
890 Lisp_Object
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
891 make_stdio_output_stream (FILE *stream, int flags)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
892 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
893 return make_stdio_stream_1 (stream, flags, "w");
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 /* #### From reading the Unix 98 specification, it appears that if we
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
897 want stdio_reader() to be completely correct, we should check for
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
898 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
899 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
900 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
901 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
902 call to stdio_reader instead of calling retry_fread() again.
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
903
771
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
904 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
905 assume that
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
906
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
907 1) this is not harmful, and
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
908 2) the error will still be reported on the second read.
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 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
911 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
912 itself, so we should do the retry_fread() again. */
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
913
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
914 static Bytecount
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
915 stdio_reader (Lstream *stream, unsigned char *data, Bytecount size)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
916 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
917 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
918 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
919 if (!val)
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
920 {
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
921 if (ferror (str->file))
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
922 return LSTREAM_ERROR;
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
923 if (feof (str->file))
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
924 return 0; /* LSTREAM_EOF; */
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
925 }
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
926 return val;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
927 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
928
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
929 static Bytecount
462
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents: 456
diff changeset
930 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
931 Bytecount size)
428
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 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
934 Bytecount val = retry_fwrite (data, 1, size, str->file);
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
935 if (!val && ferror (str->file))
771
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
936 return LSTREAM_ERROR;
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
937 return val;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
938 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
939
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
940 static int
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
941 stdio_rewinder (Lstream *stream)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
942 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
943 rewind (STDIO_STREAM_DATA (stream)->file);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
944 return 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
945 }
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 static int
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
948 stdio_seekable_p (Lstream *stream)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
949 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
950 struct stat lestat;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
951 struct stdio_stream *str = STDIO_STREAM_DATA (stream);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
952
771
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
953 if (qxe_fstat (fileno (str->file), &lestat) < 0)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
954 return 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
955 return S_ISREG (lestat.st_mode);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
956 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
957
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
958 static int
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
959 stdio_flusher (Lstream *stream)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
960 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
961 struct stdio_stream *str = STDIO_STREAM_DATA (stream);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
962 if (stream->flags & LSTREAM_FL_WRITE)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
963 return fflush (str->file);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
964 else
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
965 return 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
966 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
967
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
968 static int
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
969 stdio_closer (Lstream *stream)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
970 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
971 struct stdio_stream *str = STDIO_STREAM_DATA (stream);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
972 if (str->closing)
771
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
973 return retry_fclose (str->file);
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
974 else
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
975 if (stream->flags & LSTREAM_FL_WRITE)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
976 return fflush (str->file);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
977 else
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
978 return 0;
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
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
981 /*********** a file descriptor ***********/
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 struct filedesc_stream
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
984 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
985 int fd;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
986 int pty_max_bytes;
867
804517e16990 [xemacs-hg @ 2002-06-05 09:54:39 by ben]
ben
parents: 840
diff changeset
987 Ibyte eof_char;
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
988 int starting_pos;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
989 int current_pos;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
990 int end_pos;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
991 int chars_sans_newline;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
992 unsigned int closing :1;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
993 unsigned int allow_quit :1;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
994 unsigned int blocked_ok :1;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
995 unsigned int pty_flushing :1;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
996 unsigned int blocking_error_p :1;
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
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
999 #define FILEDESC_STREAM_DATA(stream) LSTREAM_TYPE_DATA (stream, filedesc)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1000
771
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
1001 DEFINE_LSTREAM_IMPLEMENTATION ("filedesc", filedesc);
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1002
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1003 /* 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
1004 OFFSET is the offset from the *current* file pointer that the reading
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1005 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
1006 ignored when writing); -1 for unlimited. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1007 static Lisp_Object
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1008 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
1009 const char *mode)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1010 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1011 Lstream *lstr = Lstream_new (lstream_filedesc, mode);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1012 struct filedesc_stream *fstr = FILEDESC_STREAM_DATA (lstr);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1013 fstr->fd = filedesc;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1014 fstr->closing = !!(flags & LSTR_CLOSING);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1015 fstr->allow_quit = !!(flags & LSTR_ALLOW_QUIT);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1016 fstr->blocked_ok = !!(flags & LSTR_BLOCKED_OK);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1017 fstr->pty_flushing = !!(flags & LSTR_PTY_FLUSHING);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1018 fstr->blocking_error_p = 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1019 fstr->chars_sans_newline = 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1020 fstr->starting_pos = lseek (filedesc, offset, SEEK_CUR);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1021 fstr->current_pos = max (fstr->starting_pos, 0);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1022 if (count < 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1023 fstr->end_pos = -1;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1024 else
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1025 fstr->end_pos = fstr->starting_pos + count;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1026 lstr->flags |= LSTREAM_FL_CLOSE_AT_DISKSAVE;
793
e38acbeb1cae [xemacs-hg @ 2002-03-29 04:46:17 by ben]
ben
parents: 788
diff changeset
1027 return wrap_lstream (lstr);
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1028 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1029
814
a634e3b7acc8 [xemacs-hg @ 2002-04-14 12:41:59 by ben]
ben
parents: 800
diff changeset
1030 /* Flags:
a634e3b7acc8 [xemacs-hg @ 2002-04-14 12:41:59 by ben]
ben
parents: 800
diff changeset
1031
a634e3b7acc8 [xemacs-hg @ 2002-04-14 12:41:59 by ben]
ben
parents: 800
diff changeset
1032 LSTR_CLOSING
a634e3b7acc8 [xemacs-hg @ 2002-04-14 12:41:59 by ben]
ben
parents: 800
diff changeset
1033 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
1034
a634e3b7acc8 [xemacs-hg @ 2002-04-14 12:41:59 by ben]
ben
parents: 800
diff changeset
1035 LSTR_ALLOW_QUIT
a634e3b7acc8 [xemacs-hg @ 2002-04-14 12:41:59 by ben]
ben
parents: 800
diff changeset
1036 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
1037
a634e3b7acc8 [xemacs-hg @ 2002-04-14 12:41:59 by ben]
ben
parents: 800
diff changeset
1038 LSTR_PTY_FLUSHING
a634e3b7acc8 [xemacs-hg @ 2002-04-14 12:41:59 by ben]
ben
parents: 800
diff changeset
1039 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
1040 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
1041 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
1042
a634e3b7acc8 [xemacs-hg @ 2002-04-14 12:41:59 by ben]
ben
parents: 800
diff changeset
1043 LSTR_BLOCKED_OK
a634e3b7acc8 [xemacs-hg @ 2002-04-14 12:41:59 by ben]
ben
parents: 800
diff changeset
1044 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
1045 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
1046 of bytes written out.
a634e3b7acc8 [xemacs-hg @ 2002-04-14 12:41:59 by ben]
ben
parents: 800
diff changeset
1047 */
a634e3b7acc8 [xemacs-hg @ 2002-04-14 12:41:59 by ben]
ben
parents: 800
diff changeset
1048
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1049 Lisp_Object
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1050 make_filedesc_input_stream (int filedesc, int offset, int count, int flags)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1051 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1052 return make_filedesc_stream_1 (filedesc, offset, count, flags, "r");
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1053 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1054
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1055 Lisp_Object
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1056 make_filedesc_output_stream (int filedesc, int offset, int count, int flags)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1057 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1058 return make_filedesc_stream_1 (filedesc, offset, count, flags, "w");
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1059 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1060
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
1061 static Bytecount
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
1062 filedesc_reader (Lstream *stream, unsigned char *data, Bytecount size)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1063 {
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
1064 Bytecount nread;
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1065 struct filedesc_stream *str = FILEDESC_STREAM_DATA (stream);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1066 if (str->end_pos >= 0)
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
1067 size = min (size, (Bytecount) (str->end_pos - str->current_pos));
430
a5df635868b2 Import from CVS: tag r21-2-23
cvs
parents: 428
diff changeset
1068 nread = str->allow_quit ?
a5df635868b2 Import from CVS: tag r21-2-23
cvs
parents: 428
diff changeset
1069 read_allowing_quit (str->fd, data, size) :
771
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
1070 retry_read (str->fd, data, size);
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1071 if (nread > 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1072 str->current_pos += nread;
771
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
1073 if (nread == 0)
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
1074 return 0; /* LSTREAM_EOF; */
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
1075 if (nread < 0)
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
1076 return LSTREAM_ERROR;
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1077 return nread;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1078 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1079
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1080 static int
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1081 errno_would_block_p (int val)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1082 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1083 #ifdef EWOULDBLOCK
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1084 if (val == EWOULDBLOCK)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1085 return 1;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1086 #endif
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1087 #ifdef EAGAIN
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1088 if (val == EAGAIN)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1089 return 1;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1090 #endif
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1091 return 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1092 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1093
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
1094 static Bytecount
462
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents: 456
diff changeset
1095 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
1096 Bytecount size)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1097 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1098 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
1099 Bytecount retval;
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1100 int need_newline = 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1101
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1102 /* This function would be simple if it were not for the blasted
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1103 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
1104 the PTY drivers right so this problem doesn't exist?
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1105
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1106 Maybe all the PTY crap here should be moved into another stream
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1107 that does nothing but periodically insert EOF's as necessary. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1108 if (str->pty_flushing)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1109 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1110 /* 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
1111 const unsigned char *ptr;
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1112
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
1113 ptr = (const unsigned char *) memchr (data, '\n', size);
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1114 if (ptr)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1115 need_newline = 1;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1116 else
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1117 ptr = data + size;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1118 if (ptr - data >= str->pty_max_bytes - str->chars_sans_newline)
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 ptr = data + str->pty_max_bytes - str->chars_sans_newline;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1121 need_newline = 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1122 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1123 size = ptr - data;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1124 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1125
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1126 /**** start of non-PTY-crap ****/
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1127 if (size > 0)
430
a5df635868b2 Import from CVS: tag r21-2-23
cvs
parents: 428
diff changeset
1128 retval = str->allow_quit ?
a5df635868b2 Import from CVS: tag r21-2-23
cvs
parents: 428
diff changeset
1129 write_allowing_quit (str->fd, data, size) :
771
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
1130 retry_write (str->fd, data, size);
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1131 else
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1132 retval = 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1133 if (retval < 0 && errno_would_block_p (errno) && str->blocked_ok)
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 str->blocking_error_p = 1;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1136 return 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1137 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1138 str->blocking_error_p = 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1139 if (retval < 0)
771
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
1140 return LSTREAM_ERROR;
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1141 /**** end non-PTY-crap ****/
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 if (str->pty_flushing)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1144 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1145 str->chars_sans_newline += retval;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1146 /* Note that a newline was not among the bytes written out.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1147 Add to the number of non-newline bytes written out,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1148 and flush with an EOF if necessary. Be careful to
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1149 keep track of write errors as we go along and look
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1150 out for EWOULDBLOCK. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1151 if (str->chars_sans_newline >= str->pty_max_bytes)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1152 {
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
1153 Bytecount retval2 = str->allow_quit ?
430
a5df635868b2 Import from CVS: tag r21-2-23
cvs
parents: 428
diff changeset
1154 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
1155 retry_write (str->fd, &str->eof_char, 1);
430
a5df635868b2 Import from CVS: tag r21-2-23
cvs
parents: 428
diff changeset
1156
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1157 if (retval2 > 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1158 str->chars_sans_newline = 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1159 else if (retval2 < 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1160 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1161 /* Error writing the EOF char. If nothing got written,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1162 then treat this as an error -- either return an error
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1163 condition or set the blocking-error flag. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1164 if (retval == 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1165 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1166 if (errno_would_block_p (errno) && str->blocked_ok)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1167 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1168 str->blocking_error_p = 1;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1169 return 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1170 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1171 else
771
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
1172 return LSTREAM_ERROR;
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1173 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1174 else
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1175 return retval;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1176 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1177 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1178 }
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 /* The need_newline flag is necessary because otherwise when the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1181 first byte is a newline, we'd get stuck never writing anything
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1182 in pty-flushing mode. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1183 if (need_newline)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1184 {
867
804517e16990 [xemacs-hg @ 2002-06-05 09:54:39 by ben]
ben
parents: 840
diff changeset
1185 Ibyte nl = '\n';
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
1186 Bytecount retval2 = str->allow_quit ?
430
a5df635868b2 Import from CVS: tag r21-2-23
cvs
parents: 428
diff changeset
1187 write_allowing_quit (str->fd, &nl, 1) :
771
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
1188 retry_write (str->fd, &nl, 1);
430
a5df635868b2 Import from CVS: tag r21-2-23
cvs
parents: 428
diff changeset
1189
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1190 if (retval2 > 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1191 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1192 str->chars_sans_newline = 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1193 retval++;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1194 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1195 else if (retval2 < 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1196 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1197 /* Error writing the newline char. If nothing got written,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1198 then treat this as an error -- either return an error
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1199 condition or set the blocking-error flag. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1200 if (retval == 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1201 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1202 if (errno_would_block_p (errno) && str->blocked_ok)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1203 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1204 str->blocking_error_p = 1;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1205 return 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1206 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1207 else
771
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
1208 return LSTREAM_ERROR;
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1209 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1210 else
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1211 return retval;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1212 }
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 return retval;
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
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1218 static int
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1219 filedesc_rewinder (Lstream *stream)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1220 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1221 struct filedesc_stream *str = FILEDESC_STREAM_DATA (stream);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1222 if (str->starting_pos < 0 ||
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1223 lseek (FILEDESC_STREAM_DATA (stream)->fd, str->starting_pos,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1224 SEEK_SET) == -1)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1225 return -1;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1226 else
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1227 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1228 str->current_pos = str->starting_pos;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1229 return 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1230 }
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
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1233 static int
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1234 filedesc_seekable_p (Lstream *stream)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1235 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1236 struct filedesc_stream *str = FILEDESC_STREAM_DATA (stream);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1237 if (str->starting_pos < 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1238 return 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1239 else
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 struct stat lestat;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1242
771
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
1243 if (qxe_fstat (str->fd, &lestat) < 0)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1244 return 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1245 return S_ISREG (lestat.st_mode);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1246 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1247 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1248
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1249 static int
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1250 filedesc_closer (Lstream *stream)
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 struct filedesc_stream *str = FILEDESC_STREAM_DATA (stream);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1253 if (str->closing)
771
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
1254 return retry_close (str->fd);
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1255 else
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1256 return 0;
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
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1259 static int
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1260 filedesc_was_blocked_p (Lstream *stream)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1261 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1262 struct filedesc_stream *str = FILEDESC_STREAM_DATA (stream);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1263 return str->blocking_error_p;
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
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1266 void
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1267 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
1268 Ibyte eof_char)
428
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 struct filedesc_stream *str = FILEDESC_STREAM_DATA (stream);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1271 str->pty_max_bytes = pty_max_bytes;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1272 str->eof_char = eof_char;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1273 str->pty_flushing = 1;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1274 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1275
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1276 int
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1277 filedesc_stream_fd (Lstream *stream)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1278 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1279 struct filedesc_stream *str = FILEDESC_STREAM_DATA (stream);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1280 return str->fd;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1281 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1282
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1283 /*********** read from a Lisp string ***********/
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 #define LISP_STRING_STREAM_DATA(stream) LSTREAM_TYPE_DATA (stream, lisp_string)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1286
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1287 struct lisp_string_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 Lisp_Object obj;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1290 Bytecount init_offset;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1291 Bytecount offset, end;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1292 };
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1293
771
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
1294 DEFINE_LSTREAM_IMPLEMENTATION ("lisp-string", lisp_string);
428
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 Lisp_Object
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1297 make_lisp_string_input_stream (Lisp_Object string, Bytecount offset,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1298 Bytecount len)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1299 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1300 Lstream *lstr;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1301 struct lisp_string_stream *str;
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 CHECK_STRING (string);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1304 if (len < 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1305 len = XSTRING_LENGTH (string) - offset;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1306 assert (offset >= 0);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1307 assert (len >= 0);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1308 assert (offset + len <= XSTRING_LENGTH (string));
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1309
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1310 lstr = Lstream_new (lstream_lisp_string, "r");
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1311 str = LISP_STRING_STREAM_DATA (lstr);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1312 str->offset = offset;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1313 str->end = offset + len;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1314 str->init_offset = offset;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1315 str->obj = string;
793
e38acbeb1cae [xemacs-hg @ 2002-03-29 04:46:17 by ben]
ben
parents: 788
diff changeset
1316 return wrap_lstream (lstr);
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1317 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1318
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
1319 static Bytecount
462
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents: 456
diff changeset
1320 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
1321 Bytecount size)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1322 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1323 struct lisp_string_stream *str = LISP_STRING_STREAM_DATA (stream);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1324 /* Don't lose if the string shrank past us ... */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1325 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
1326 Ibyte *strstart = XSTRING_DATA (str->obj);
804517e16990 [xemacs-hg @ 2002-06-05 09:54:39 by ben]
ben
parents: 840
diff changeset
1327 Ibyte *start = strstart + offset;
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1328
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1329 /* ... or if someone changed the string and we ended up in the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1330 middle of a character. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1331 /* Being in the middle of a character is `normal' unless
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1332 LSTREAM_NO_PARTIAL_CHARS - mrb */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1333 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
1334 VALIDATE_IBYTEPTR_BACKWARD (start);
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1335 offset = start - strstart;
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
1336 size = min (size, (Bytecount) (str->end - offset));
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1337 memcpy (data, start, size);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1338 str->offset = offset + size;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1339 return size;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1340 }
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 static int
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1343 lisp_string_rewinder (Lstream *stream)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1344 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1345 struct lisp_string_stream *str = LISP_STRING_STREAM_DATA (stream);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1346 int pos = str->init_offset;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1347 if (pos > str->end)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1348 pos = str->end;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1349 /* Don't lose if the string shrank past us ... */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1350 pos = min (pos, XSTRING_LENGTH (str->obj));
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1351 /* ... or if someone changed the string and we ended up in the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1352 middle of a character. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1353 {
867
804517e16990 [xemacs-hg @ 2002-06-05 09:54:39 by ben]
ben
parents: 840
diff changeset
1354 Ibyte *strstart = XSTRING_DATA (str->obj);
804517e16990 [xemacs-hg @ 2002-06-05 09:54:39 by ben]
ben
parents: 840
diff changeset
1355 Ibyte *start = strstart + pos;
804517e16990 [xemacs-hg @ 2002-06-05 09:54:39 by ben]
ben
parents: 840
diff changeset
1356 VALIDATE_IBYTEPTR_BACKWARD (start);
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1357 pos = start - strstart;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1358 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1359 str->offset = pos;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1360 return 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1361 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1362
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1363 static Lisp_Object
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1364 lisp_string_marker (Lisp_Object stream)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1365 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1366 struct lisp_string_stream *str = LISP_STRING_STREAM_DATA (XLSTREAM (stream));
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1367 return str->obj;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1368 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1369
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1370 /*********** a fixed buffer ***********/
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1371
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1372 #define FIXED_BUFFER_STREAM_DATA(stream) \
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1373 LSTREAM_TYPE_DATA (stream, fixed_buffer)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1374
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1375 struct fixed_buffer_stream
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1376 {
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
1377 const unsigned char *inbuf;
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1378 unsigned char *outbuf;
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
1379 Bytecount size;
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
1380 Bytecount offset;
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1381 };
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1382
771
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
1383 DEFINE_LSTREAM_IMPLEMENTATION ("fixed-buffer", fixed_buffer);
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1384
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1385 Lisp_Object
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
1386 make_fixed_buffer_input_stream (const void *buf, Bytecount size)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1387 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1388 Lstream *lstr = Lstream_new (lstream_fixed_buffer, "r");
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1389 struct fixed_buffer_stream *str = FIXED_BUFFER_STREAM_DATA (lstr);
440
8de8e3f6228a Import from CVS: tag r21-2-28
cvs
parents: 430
diff changeset
1390 str->inbuf = (const unsigned char *) buf;
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1391 str->size = size;
793
e38acbeb1cae [xemacs-hg @ 2002-03-29 04:46:17 by ben]
ben
parents: 788
diff changeset
1392 return wrap_lstream (lstr);
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1393 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1394
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1395 Lisp_Object
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
1396 make_fixed_buffer_output_stream (void *buf, Bytecount size)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1397 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1398 Lstream *lstr = Lstream_new (lstream_fixed_buffer, "w");
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1399 struct fixed_buffer_stream *str = FIXED_BUFFER_STREAM_DATA (lstr);
440
8de8e3f6228a Import from CVS: tag r21-2-28
cvs
parents: 430
diff changeset
1400 str->outbuf = (unsigned char *) buf;
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1401 str->size = size;
793
e38acbeb1cae [xemacs-hg @ 2002-03-29 04:46:17 by ben]
ben
parents: 788
diff changeset
1402 return wrap_lstream (lstr);
428
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
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
1405 static Bytecount
462
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents: 456
diff changeset
1406 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
1407 Bytecount size)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1408 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1409 struct fixed_buffer_stream *str = FIXED_BUFFER_STREAM_DATA (stream);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1410 size = min (size, str->size - str->offset);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1411 memcpy (data, str->inbuf + str->offset, size);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1412 str->offset += size;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1413 return size;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1414 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1415
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
1416 static Bytecount
462
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents: 456
diff changeset
1417 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
1418 Bytecount size)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1419 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1420 struct fixed_buffer_stream *str = FIXED_BUFFER_STREAM_DATA (stream);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1421 if (str->offset == str->size)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1422 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1423 /* 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
1424 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
1425 will try again and again to write it out. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1426 return size;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1427 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1428 size = min (size, str->size - str->offset);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1429 memcpy (str->outbuf + str->offset, data, size);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1430 str->offset += size;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1431 return size;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1432 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1433
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1434 static int
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1435 fixed_buffer_rewinder (Lstream *stream)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1436 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1437 FIXED_BUFFER_STREAM_DATA (stream)->offset = 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1438 return 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1439 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1440
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
1441 const unsigned char *
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1442 fixed_buffer_input_stream_ptr (Lstream *stream)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1443 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1444 assert (stream->imp == lstream_fixed_buffer);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1445 return FIXED_BUFFER_STREAM_DATA (stream)->inbuf;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1446 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1447
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1448 unsigned char *
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1449 fixed_buffer_output_stream_ptr (Lstream *stream)
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 assert (stream->imp == lstream_fixed_buffer);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1452 return FIXED_BUFFER_STREAM_DATA (stream)->outbuf;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1453 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1454
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1455 /*********** write to a resizing buffer ***********/
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 #define RESIZING_BUFFER_STREAM_DATA(stream) \
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1458 LSTREAM_TYPE_DATA (stream, resizing_buffer)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1459
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1460 struct resizing_buffer_stream
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 unsigned char *buf;
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
1463 Bytecount allocked;
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1464 int max_stored;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1465 int stored;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1466 };
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1467
771
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
1468 DEFINE_LSTREAM_IMPLEMENTATION ("resizing-buffer", resizing_buffer);
428
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 Lisp_Object
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1471 make_resizing_buffer_output_stream (void)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1472 {
793
e38acbeb1cae [xemacs-hg @ 2002-03-29 04:46:17 by ben]
ben
parents: 788
diff changeset
1473 return wrap_lstream (Lstream_new (lstream_resizing_buffer, "w"));
428
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
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
1476 static Bytecount
462
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents: 456
diff changeset
1477 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
1478 Bytecount size)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1479 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1480 struct resizing_buffer_stream *str = RESIZING_BUFFER_STREAM_DATA (stream);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1481 DO_REALLOC (str->buf, str->allocked, str->stored + size, unsigned char);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1482 memcpy (str->buf + str->stored, data, size);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1483 str->stored += size;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1484 str->max_stored = max (str->max_stored, str->stored);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1485 return size;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1486 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1487
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1488 static int
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1489 resizing_buffer_rewinder (Lstream *stream)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1490 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1491 RESIZING_BUFFER_STREAM_DATA (stream)->stored = 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1492 return 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1493 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1494
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1495 static int
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1496 resizing_buffer_closer (Lstream *stream)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1497 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1498 struct resizing_buffer_stream *str = RESIZING_BUFFER_STREAM_DATA (stream);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1499 if (str->buf)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1500 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1501 xfree (str->buf);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1502 str->buf = 0;
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 return 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1505 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1506
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1507 unsigned char *
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1508 resizing_buffer_stream_ptr (Lstream *stream)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1509 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1510 return RESIZING_BUFFER_STREAM_DATA (stream)->buf;
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
788
026c5bf9c134 [xemacs-hg @ 2002-03-21 07:29:57 by ben]
ben
parents: 771
diff changeset
1513 Lisp_Object
026c5bf9c134 [xemacs-hg @ 2002-03-21 07:29:57 by ben]
ben
parents: 771
diff changeset
1514 resizing_buffer_to_lisp_string (Lstream *stream)
026c5bf9c134 [xemacs-hg @ 2002-03-21 07:29:57 by ben]
ben
parents: 771
diff changeset
1515 {
026c5bf9c134 [xemacs-hg @ 2002-03-21 07:29:57 by ben]
ben
parents: 771
diff changeset
1516 return make_string (resizing_buffer_stream_ptr (stream),
026c5bf9c134 [xemacs-hg @ 2002-03-21 07:29:57 by ben]
ben
parents: 771
diff changeset
1517 Lstream_byte_count (stream));
026c5bf9c134 [xemacs-hg @ 2002-03-21 07:29:57 by ben]
ben
parents: 771
diff changeset
1518 }
026c5bf9c134 [xemacs-hg @ 2002-03-21 07:29:57 by ben]
ben
parents: 771
diff changeset
1519
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1520 /*********** write to an unsigned-char dynarr ***********/
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 /* 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
1523 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
1524 is Ibyte or Extbyte), just cast to unsigned_char_dynarr. */
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1525
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1526 #define DYNARR_STREAM_DATA(stream) \
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1527 LSTREAM_TYPE_DATA (stream, dynarr)
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 struct dynarr_stream
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1530 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1531 unsigned_char_dynarr *dyn;
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
771
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
1534 DEFINE_LSTREAM_IMPLEMENTATION ("dynarr", dynarr);
428
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 Lisp_Object
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1537 make_dynarr_output_stream (unsigned_char_dynarr *dyn)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1538 {
793
e38acbeb1cae [xemacs-hg @ 2002-03-29 04:46:17 by ben]
ben
parents: 788
diff changeset
1539 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
1540
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1541 DYNARR_STREAM_DATA (XLSTREAM (obj))->dyn = dyn;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1542 return obj;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1543 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1544
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
1545 static Bytecount
462
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents: 456
diff changeset
1546 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
1547 Bytecount size)
428
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 struct dynarr_stream *str = DYNARR_STREAM_DATA (stream);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1550 Dynarr_add_many (str->dyn, data, size);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1551 return size;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1552 }
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 static int
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1555 dynarr_rewinder (Lstream *stream)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1556 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1557 Dynarr_reset (DYNARR_STREAM_DATA (stream)->dyn);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1558 return 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1559 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1560
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1561 static int
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1562 dynarr_closer (Lstream *stream)
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 return 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1565 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1566
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1567 /************ read from or write to a Lisp buffer ************/
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1568
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1569 /* Note: Lisp-buffer read streams never return partial characters,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1570 and Lisp-buffer write streams expect to never get partial
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1571 characters. */
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 #define LISP_BUFFER_STREAM_DATA(stream) \
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1574 LSTREAM_TYPE_DATA (stream, lisp_buffer)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1575
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1576 struct lisp_buffer_stream
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 buffer;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1579 Lisp_Object orig_start;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1580 /* we use markers to properly deal with insertion/deletion */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1581 Lisp_Object start, end;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1582 int flags;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1583 };
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1584
771
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
1585 DEFINE_LSTREAM_IMPLEMENTATION ("lisp-buffer", lisp_buffer);
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1586
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1587 static Lisp_Object
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
1588 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
1589 int flags, const Char_ASCII *mode)
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 Lstream *lstr;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1592 struct lisp_buffer_stream *str;
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
1593 Charbpos bmin, bmax;
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1594 int reading = !strcmp (mode, "r");
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 /* Make sure the luser didn't pass "w" in. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1597 if (!strcmp (mode, "w"))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1598 abort ();
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1599
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1600 if (flags & LSTR_IGNORE_ACCESSIBLE)
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 bmin = BUF_BEG (buf);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1603 bmax = BUF_Z (buf);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1604 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1605 else
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1606 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1607 bmin = BUF_BEGV (buf);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1608 bmax = BUF_ZV (buf);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1609 }
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 if (start == -1)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1612 start = bmin;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1613 if (end == -1)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1614 end = bmax;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1615 assert (bmin <= start);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1616 assert (start <= bmax);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1617 if (reading)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1618 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1619 assert (bmin <= end);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1620 assert (end <= bmax);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1621 assert (start <= end);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1622 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1623
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1624 lstr = Lstream_new (lstream_lisp_buffer, mode);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1625 str = LISP_BUFFER_STREAM_DATA (lstr);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1626 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1627 Lisp_Object marker;
793
e38acbeb1cae [xemacs-hg @ 2002-03-29 04:46:17 by ben]
ben
parents: 788
diff changeset
1628 Lisp_Object buffer = wrap_buffer (buf);
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1629
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1630 marker = Fmake_marker ();
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1631 Fset_marker (marker, make_int (start), buffer);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1632 str->start = marker;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1633 marker = Fmake_marker ();
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1634 Fset_marker (marker, make_int (start), buffer);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1635 str->orig_start = marker;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1636 if (reading)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1637 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1638 marker = Fmake_marker ();
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1639 Fset_marker (marker, make_int (end), buffer);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1640 str->end = marker;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1641 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1642 else
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1643 str->end = Qnil;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1644 str->buffer = buffer;
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 str->flags = flags;
793
e38acbeb1cae [xemacs-hg @ 2002-03-29 04:46:17 by ben]
ben
parents: 788
diff changeset
1647 return wrap_lstream (lstr);
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1648 }
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 Lisp_Object
826
6728e641994e [xemacs-hg @ 2002-05-05 11:30:15 by ben]
ben
parents: 814
diff changeset
1651 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
1652 Charbpos end, int flags)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1653 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1654 return make_lisp_buffer_stream_1 (buf, start, end, flags, "r");
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1655 }
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 Lisp_Object
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
1658 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
1659 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1660 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
1661
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1662 Lstream_set_character_mode (XLSTREAM (lstr));
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1663 return lstr;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1664 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1665
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
1666 static Bytecount
867
804517e16990 [xemacs-hg @ 2002-06-05 09:54:39 by ben]
ben
parents: 840
diff changeset
1667 lisp_buffer_reader (Lstream *stream, Ibyte *data, Bytecount size)
428
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 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
1670 Bytebpos start;
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
1671 Bytebpos end;
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1672 struct buffer *buf = XBUFFER (str->buffer);
826
6728e641994e [xemacs-hg @ 2002-05-05 11:30:15 by ben]
ben
parents: 814
diff changeset
1673 Bytecount src_used;
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1674
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1675 if (!BUFFER_LIVE_P (buf))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1676 return 0; /* Fut. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1677
826
6728e641994e [xemacs-hg @ 2002-05-05 11:30:15 by ben]
ben
parents: 814
diff changeset
1678 start = byte_marker_position (str->start);
6728e641994e [xemacs-hg @ 2002-05-05 11:30:15 by ben]
ben
parents: 814
diff changeset
1679 end = byte_marker_position (str->end);
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1680 if (!(str->flags & LSTR_IGNORE_ACCESSIBLE))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1681 {
826
6728e641994e [xemacs-hg @ 2002-05-05 11:30:15 by ben]
ben
parents: 814
diff changeset
1682 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
1683 BYTE_BUF_ZV (buf));
6728e641994e [xemacs-hg @ 2002-05-05 11:30:15 by ben]
ben
parents: 814
diff changeset
1684 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
1685 BYTE_BUF_ZV (buf));
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1686 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1687
826
6728e641994e [xemacs-hg @ 2002-05-05 11:30:15 by ben]
ben
parents: 814
diff changeset
1688 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
1689 FORMAT_DEFAULT, Qnil, &src_used);
6728e641994e [xemacs-hg @ 2002-05-05 11:30:15 by ben]
ben
parents: 814
diff changeset
1690 end = start + src_used;
428
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 if (EQ (buf->selective_display, Qt) && str->flags & LSTR_SELECTIVE)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1693 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1694 /* 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
1695 Ibyte *p;
840
1e4e42de23d5 [xemacs-hg @ 2002-05-14 13:03:54 by ben]
ben
parents: 826
diff changeset
1696 for (p = data; p < data + src_used; p++)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1697 if (*p == '\r')
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1698 *p = '\n';
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
826
6728e641994e [xemacs-hg @ 2002-05-05 11:30:15 by ben]
ben
parents: 814
diff changeset
1701 set_byte_marker_position (str->start, end);
6728e641994e [xemacs-hg @ 2002-05-05 11:30:15 by ben]
ben
parents: 814
diff changeset
1702 return size;
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
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
1705 static Bytecount
867
804517e16990 [xemacs-hg @ 2002-06-05 09:54:39 by ben]
ben
parents: 840
diff changeset
1706 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
1707 Bytecount size)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1708 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1709 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
1710 Charbpos pos;
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1711 struct buffer *buf = XBUFFER (str->buffer);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1712
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1713 if (!BUFFER_LIVE_P (buf))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1714 return 0; /* Fut. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1715
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1716 pos = marker_position (str->start);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1717 pos += buffer_insert_raw_string_1 (buf, pos, data, size, 0);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1718 set_marker_position (str->start, pos);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1719 return size;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1720 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1721
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1722 static int
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1723 lisp_buffer_rewinder (Lstream *stream)
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 struct lisp_buffer_stream *str =
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1726 LISP_BUFFER_STREAM_DATA (stream);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1727 struct buffer *buf = XBUFFER (str->buffer);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1728 long pos = marker_position (str->orig_start);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1729 if (!BUFFER_LIVE_P (buf))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1730 return -1; /* Fut. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1731 if (pos > BUF_ZV (buf))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1732 pos = BUF_ZV (buf);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1733 if (pos < marker_position (str->orig_start))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1734 pos = marker_position (str->orig_start);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1735 if (MARKERP (str->end) && pos > marker_position (str->end))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1736 pos = marker_position (str->end);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1737 set_marker_position (str->start, pos);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1738 return 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1739 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1740
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1741 static Lisp_Object
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1742 lisp_buffer_marker (Lisp_Object stream)
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 struct lisp_buffer_stream *str =
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1745 LISP_BUFFER_STREAM_DATA (XLSTREAM (stream));
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1746
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1747 mark_object (str->start);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1748 mark_object (str->end);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1749 return str->buffer;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1750 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1751
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
1752 Charbpos
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1753 lisp_buffer_stream_startpos (Lstream *stream)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1754 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1755 return marker_position (LISP_BUFFER_STREAM_DATA (stream)->start);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1756 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1757
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 /************************************************************************/
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1760 /* initialization */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1761 /************************************************************************/
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 void
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1764 lstream_type_create (void)
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 LSTREAM_HAS_METHOD (stdio, reader);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1767 LSTREAM_HAS_METHOD (stdio, writer);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1768 LSTREAM_HAS_METHOD (stdio, rewinder);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1769 LSTREAM_HAS_METHOD (stdio, seekable_p);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1770 LSTREAM_HAS_METHOD (stdio, flusher);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1771 LSTREAM_HAS_METHOD (stdio, closer);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1772
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1773 LSTREAM_HAS_METHOD (filedesc, reader);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1774 LSTREAM_HAS_METHOD (filedesc, writer);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1775 LSTREAM_HAS_METHOD (filedesc, was_blocked_p);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1776 LSTREAM_HAS_METHOD (filedesc, rewinder);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1777 LSTREAM_HAS_METHOD (filedesc, seekable_p);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1778 LSTREAM_HAS_METHOD (filedesc, closer);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1779
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1780 LSTREAM_HAS_METHOD (lisp_string, reader);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1781 LSTREAM_HAS_METHOD (lisp_string, rewinder);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1782 LSTREAM_HAS_METHOD (lisp_string, marker);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1783
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1784 LSTREAM_HAS_METHOD (fixed_buffer, reader);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1785 LSTREAM_HAS_METHOD (fixed_buffer, writer);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1786 LSTREAM_HAS_METHOD (fixed_buffer, rewinder);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1787
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1788 LSTREAM_HAS_METHOD (resizing_buffer, writer);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1789 LSTREAM_HAS_METHOD (resizing_buffer, rewinder);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1790 LSTREAM_HAS_METHOD (resizing_buffer, closer);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1791
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1792 LSTREAM_HAS_METHOD (dynarr, writer);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1793 LSTREAM_HAS_METHOD (dynarr, rewinder);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1794 LSTREAM_HAS_METHOD (dynarr, closer);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1795
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1796 LSTREAM_HAS_METHOD (lisp_buffer, reader);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1797 LSTREAM_HAS_METHOD (lisp_buffer, writer);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1798 LSTREAM_HAS_METHOD (lisp_buffer, rewinder);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1799 LSTREAM_HAS_METHOD (lisp_buffer, marker);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1800 }
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 void
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1803 reinit_vars_of_lstream (void)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1804 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1805 int i;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1806
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1807 for (i = 0; i < countof (Vlstream_free_list); i++)
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 Vlstream_free_list[i] = Qnil;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1810 staticpro_nodump (&Vlstream_free_list[i]);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1811 }
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 vars_of_lstream (void)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1816 {
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
1817 INIT_LRECORD_IMPLEMENTATION (lstream);
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 440
diff changeset
1818
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1819 reinit_vars_of_lstream ();
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1820 }