/*
 *   fstream.h
 *
 *   C++ IOStreams specialized for use with files.
 *
 *           Copyright (c) 1991-1992, MetaWare Incorporated
 */

#ifndef __FSTREAM_H
#define __FSTREAM_H
#pragma push_align_members(64);

#if _MSDOS && !__EXCEPTIONS__
    #pragma off(exception_aware_class);
#elif _MSDOS || _MSNT || _OS2
    #pragma on(exception_aware_class);
#endif

#if _MSNT && _DLL && !_DLLBUILD
    #pragma on(dllimport);
#endif

#c_include <iostream.h>

#pragma on(nodebug)
/*
 *   Class filebuf:
 *
 *      streambuf specialized for use with files.
 *      Supports associated file descriptor, seek, read and write
 *      to external file.
 *
 */

class  filebuf : public streambuf {

private:
	void		fb_checkstate();

protected:
	int		xfd;		// File descriptor for this filebuf.
	int		mode;		// Open mode of file descriptor.
	char		opened;		// TRUE == xfd is open.
	streampos	last_seek;	// Position after last seek.
	char* 		in_start;
	int		last_op();	// ???  Not implemented.
	char		lahead[2];	// Input buffer for unbuffered filebufs.
	int		phy_in_avail(); // Physical characters remaining

public:
	static const int openprot;	// Default permissions = 0644(rw,r,r)

	void		fb_dbp(int __level);

			filebuf();	// Buffered, no handle, not open.

					// Buffered, __handle already open.
			filebuf(int __handle);

					// Buffered, __handle already open.
			filebuf(int __handle, char* __buf, int __len);

	int		is_open() const { return opened; }
	int		fd() const { return xfd; }

					// Open file.
	filebuf*	_UNSAFE(open)(const char *__pathname, long __mode,
				long __prot=filebuf::openprot);

					// Use __handle, fail if already open.
	filebuf*	attach(int __handle);

					// Sync and close file.
	filebuf* 	_UNSAFE(close)();

					// Sync and close file.
			~filebuf();

// virtuals
	virtual int	_UNSAFE(overflow)(int=EOF);
	virtual int	_UNSAFE(underflow)();
	virtual int	_UNSAFE(sync)();
	virtual streampos
			_UNSAFE(seekoff)(streamoff __offset,
				ios::seek_dir __dir, long __mode);
	virtual streambuf*
			setbuf(char* __buf, int __len);
#if _MT
public:
	filebuf*	open(const char *__pathname, long __mode,
				long __prot=filebuf::openprot);
	virtual int	overflow(int=EOF);
	virtual int	underflow();
	virtual int	sync();
	filebuf* 	close();
	virtual streampos
			seekoff(streamoff __offset, ios::seek_dir __dir,
				long __mode);
#endif
	};


/*
 *   Class fstreambase:
 *
 *      Base class for input/output functions on filebufs.
 *
 */

class fstreambase : virtual public ios { 

private:
	void		check_stat();
	filebuf		buf;

protected:
	void		verify(int);

public:
			fstreambase();
	
			fstreambase(const char* __name, long __mode,
					long __prot=filebuf::openprot);
			fstreambase(int __handle);
			fstreambase(int __handle, char* __buf, int __len);
			~fstreambase();
	void		_UNSAFE(open)(const char* __name, long __mode, 
					long __prot=filebuf::openprot);
	void		attach(int __handle);
	void		close();
	filebuf*	setbuf(char* __buf, int __len);
	filebuf*	rdbuf() { return &buf; }
#if _MT
public:
	void		open(const char* __name, long __mode, 
					long __prot=filebuf::openprot);
#endif
	};

/*
 *   Class ifstream:
 *
 *      istream specialized for files.
 *
 */

class ifstream : public fstreambase, public istream {
public:
			ifstream();
			ifstream(const char* __name, long __mode=ios::in,
					long __prot=filebuf::openprot);
			ifstream(int __handle);
			ifstream(int __handle, char* __buf, int __len);
			~ifstream();

	filebuf*	rdbuf() { return fstreambase::rdbuf(); }
	void		open(const char* __fname, long __mode=ios::in, 
					long __prot=filebuf::openprot);
	};

/*
 *   Class ofstream:
 *
 *      ostream specialized for files.
 *
 */

class ofstream : public fstreambase, public ostream {
public:
			ofstream();
			ofstream(const char* __name, long __mode=ios::out,
					long __prot=filebuf::openprot);
			ofstream(int __handle);
			ofstream(int __handle, char* __buf, int __len);
			~ofstream();

	filebuf*	rdbuf() { return fstreambase::rdbuf(); }
	void		open(const char* __name, long __mode=ios::out, 
					long __prot=filebuf::openprot);
	};

/*
 *   Class fstream:
 *
 *      iostream specialized for files.
 *
 */

class fstream : public fstreambase, public iostream {
public:
			fstream();
	
			fstream(const char* __name, long __mode,
					long __prot=filebuf::openprot);
			fstream(int __handle);
			fstream(int __handle, char* __buf, int __len);
			~fstream();
	filebuf*	rdbuf() { return fstreambase::rdbuf(); }
	void		open(const char* __name, long __mode, 
				long __prot=filebuf::openprot);
	};
#pragma pop(nodebug)

#if _MSNT && _DLL && !_DLLBUILD
    #pragma pop(dllimport);
#endif

#if _MSDOS || _MSNT || _OS2
    #pragma pop(exception_aware_class);
#endif


#pragma pop_align_members();
#endif // __FSTREAM_H


/**          Copyright (c) 1991-1993, MetaWare Incorporated             **/
