|
|
#include <iostream.h>typedef long streamoff, streampos; class ios { public: enum seek_dir { beg, cur, end }; enum open_mode { in, out, ate, app, trunc, nocreate, noreplace }; //
and lots of other stuff, see ios(C++) ...
} ;#include <fstream.h>
class filebuf : public streambuf { public: static const int openprot ; /* default protection for open */
filebuf() ; ~filebuf() ; filebuf(int d); filebuf(int d, char* p, int len) ;
filebuf* attach(int d) ; int detach() ; filebuf* close(); int fd(); int is_open(); filebuf* open(char *name, int omode, int prot=openprot) ; streampos seekoff(streamoff, seek_dir, int omode) ; streampos seekpos(streampos, int omode) ; streambuf* setbuf(char* p, int len) ; int sync() ; };
filebuf
s
specialize
streambuf
s
to use a file as a source or sink of characters.
Characters are consumed by doing
writes to the
file, and are produced by doing
reads.
When the file is seekable,
a filebuf
allows seeks.
At least 4 characters of putback are guaranteed.
When the file permits reading and writing, the filebuf
permits
both storing and fetching.
No special action is required between gets and puts
(unlike stdio).
A filebuf
that is connected to a file descriptor is said
to be open.
Files are opened by default with a protection mode of openprot
,
which is 0644.
The
reserve area
(or buffer, see
sbuf.pub(C++)
and
sbuf.prot(C++))
is allocated automatically if one is not specified explicitly
with a constructor or a call to setbuf()
.
filebuf
s can also be made unbuffered
with certain arguments to the constructor or setbuf()
,
in which case a system call is made for each character
that is read or written.
The get
and put
pointers into the reserve area
are conceptually tied together; they behave as a single pointer.
Therefore, the descriptions below refer to a single get/put pointer.
In the descriptions below, assume:
filebuf
filebuf*
streambuf*
int
s
char*
s
int
representing an open_mode
streamoff
streampos
's
seek_dir
filebuf()
filebuf
.
filebuf(
d)
filebuf
connected to file descriptor d.
filebuf(
d,
p,
len)
filebuf
connected to file descriptor d
and initialized to use the reserve area starting at p and containing
len bytes.
If p is null or len is zero or less,
the filebuf
will be unbuffered.
.attach(
d)
attach()
normally returns &
f,
but returns 0 if f is already open.
.detach()
close()
should call this function before close()
.
.close()
close()
returns &
f unless errors occur, in which case it
returns 0
.
Even if errors occur, close()
leaves the file descriptor and
f closed.
.fd()
.is_open()
.open(
name,
mode,
prot)
ios::nocreate
is specified in mode.
By default, prot is filebuf::openprot
, which is 0644.
Failure occurs if f is already open.
open()
normally returns &
f,
but if an error occurs it returns 0.
The members of open_mode
are bits that may be or'ed together.
(Because the or'ing returns an int
, open()
takes an
int
rather than an open_mode
argument.)
The meanings of these bits in mode are described in detail
in
fstream(C++).
.seekoff(
off,
dir,
mode)
seekoff()
returns
p, the new position, or EOF if
a failure occurs.
The position of the file after a failure is undefined.
.seekpos(
pos,
mode)
seekpos()
normally returns pos,
but on failure it returns EOF.
.setbuf(
ptr,
len)
setbuf()
normally returns &
f.
However, if f is open and a buffer has been allocated, no changes
are made to the reserve area or to the buffering status,
and setbuf()
returns 0.
.sync()
.fd()
.
This means it may write characters to the file if some have been buffered for
output or attempt to reposition (seek) the file if characters have
been read and buffered for input.
Normally, sync()
returns 0, but it returns EOF if
synchronization is not possible.
Sometimes it is necessary to guarantee that certain
characters are written together.
To do this, the program should use setbuf()
(or a constructor)
to guarantee that the reserve area is at least as large as
the number of characters that must be written together.
It can then call sync()
,
then store the characters,
then call sync()
again.
attach()
and the constructors should test if the file descriptor they
are given is open, but I can't figure out a portable way to do that.
There is no way to force atomic reads.
The UNIX system does not usually report failures of seek (e.g.,
on a tty), so a filebuf
does not either.