mud++0.26/etc/
mud++0.26/etc/guilds/
mud++0.26/log/
mud++0.26/mudC/
mud++0.26/player/
mud++0.26/src/unix/
/*
....[@@@..[@@@..............[@.................. MUD++ is a written from
....[@..[@..[@..[@..[@..[@@@@@....[@......[@.... scratch multi-user swords and
....[@..[@..[@..[@..[@..[@..[@..[@@@@@..[@@@@@.. sorcery game written in C++.
....[@......[@..[@..[@..[@..[@....[@......[@.... This server is an ongoing
....[@......[@..[@@@@@..[@@@@@.................. development project.  All 
................................................ contributions are welcome. 
....Copyright(C).1995.Melvin.Smith.............. Enjoy. 
------------------------------------------------------------------------------
Melvin Smith (aka Fusion)         msmith@hom.net 
MUD++ development mailing list    mudpp-list@mailhost.net
------------------------------------------------------------------------------
io.h
*/


// This is a quick hack to get around being dependant on iostream
// Not robust, etc.
// Basic 1 hour job.
// -Fusion

#ifndef _STREAM_H
#define _STREAM_H

#include <sys/types.h>
#include <sys/stat.h>

#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#include <stdio.h>

#if !defined(WIN32)
#include <sys/mman.h>
#else
#include <io.h>
#include <process.h>
#include <sys/unistd.h>
#endif

#include "osdepend.h"
#include "config.h"

#ifdef ultrix
// All ULTRIX I know have no prototypes for mmap(), munmap()
// Even so, mmap doesn't work on ULTRIX in my experience.
extern "C"
{
	caddr_t mmap( caddr_t, size_t, int, int, int, off_t );
	int munmap( caddr_t, size_t );
}
#endif

#define endl '\n'

#define CACHE_SIZE 1

#define STR_OPEN 1
#define STR_EOF  2
#define STR_NOTMAPPED 4  // This means mmap() failed and class had to allocate.

#ifndef MAP_FILE
#define MAP_FILE 0  // non BSD systems.
#endif

class Stream
{
	protected:
		int flags;
		int fd;
	public:
		Stream()
		:	flags(0), fd(0)
		{
		}

		Stream( int filedesc )
		:	flags( STR_OPEN ), fd( filedesc )
		{
		}

		virtual ~Stream()
		{
		}

		virtual operator bool() { return (bool) flags & STR_OPEN; }
		virtual int open() = 0; 
		virtual int open( const char * ) = 0; 
		virtual void close() = 0; 
		virtual void flush() = 0; 
};



class OStream : public Stream
{
	private:
		char cache[ CACHE_SIZE ];
		char *ptr;
		char *highwater;
	public:
		OStream()
		:	Stream( STDOUT_FILENO ),
			ptr( cache ), highwater( cache + CACHE_SIZE )
		{
		}

		OStream( int filedesc )
		:	Stream( filedesc ),
			ptr( cache ), highwater( cache + CACHE_SIZE )
		{
		}

		OStream( const char * );
		OStream( const char *, int );
		virtual ~OStream();
		virtual OStream & operator << ( const char * );
		virtual OStream & operator << ( char * x )
			{	return (*this) << (const char *)x;	}
		virtual OStream & operator << ( int );
		virtual OStream & operator << ( long );
		virtual OStream & operator << ( unsigned long );
		virtual OStream & operator << ( char );
		virtual OStream & operator << ( short int );
		virtual OStream & operator << ( unsigned short int );
		virtual int open();
		virtual int open( const char * );
		virtual void close();
		virtual void flush();

		static const int APPEND = 1;
};


// My implementation of the standard C++ 'cout'
extern OStream Cout;


class IStream : public Stream
{
	private:
		int line;
		char *ptr;
		char *cache;
		struct stat stats;

	public:
		IStream()
		: Stream(), line(1), ptr(0), cache(0)
		{
		}

		IStream( const char *fname );

		virtual ~IStream();

		long getFileSize() { return stats.st_size; }
		long getLineNo() { return line; }
		long getLineNum() { return line; }
		const char * getBuf() { return cache; }
		IStream & operator >> ( char * );
		IStream & operator >> ( int );
		IStream & operator >> ( char & );
		IStream & operator >> ( unsigned long int );

		int open( const char * );

		// incomplete methods
		int open() { return -1; }
		void flush() {}

		operator bool()
		{
			if( ptr && *ptr )
				return true;
			return false;
		}

		bool eof()
		{
			if( ptr && *ptr )
				return false;
			return true;
		}

		void putback();
		char get( char &ch );
		char *getline( char *buf );
		void close();
};


#include <stdlib.h>
#include <string.h>
#include <ctype.h>

#define TERM_CHAR '~'


class InFile : public IStream
{
	private:
		char fname[256];

	public:
		InFile()
		{
			strcpy( fname, "(filename unknown)" );
		}

		InFile( const char *name )
		:	IStream( name )
		{
			strcpy( fname, name );
		} 

		const char *getFileName() { return fname; }
		void error( const char * );
		char *getstring( char *buf );
		char *getword( char *buf );
		int getnum();
		unsigned long getlong();
		void getbitfield( unsigned long * );
		void skipline();
};


inline void InFile::skipline()
{
	char ch;
	while( !eof() )
	{
		get( ch );
		if( ch == '\n' || ch == '\r' )
		{
			get( ch );
			if( ch != '\n' && ch != '\r' )
				putback();
			return;
		}		
	}
}


class OutFile : public OStream
{
	protected:
	public:
		OutFile()
		{
		}

		OutFile( const char *name )
		:	OStream( name )
		{
		}

		OutFile( const char *name, int options )
		:	OStream(name, options)
		{
		}

		void putbitfield( const unsigned long *, int );

};


inline void OutFile::putbitfield( const unsigned long * field, int num )
{
	*this << num;

	for( int i = 0; i < num; i++ )
	{
		*this << ' ';
		*this << field[i]; 
	}
}

#endif