mud++0.35/etc/
mud++0.35/etc/guilds/
mud++0.35/help/propert/
mud++0.35/mudC/
mud++0.35/player/
mud++0.35/src/interface/
mud++0.35/src/os/cygwin32/
mud++0.35/src/os/win32/
mud++0.35/src/os/win32/bcppbuilder/
mud++0.35/src/osaddon/
mud++0.35/src/util/
/*
....[@@@..[@@@..............[@.................. 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@van.ml.org
------------------------------------------------------------------------------
string.h
*/

// 25 Apr 1995  Written by Fusion <msmith@hom.net>
// 25 Apr 1995  Casual hacking by Furey <mec@duracef.shout.net>

#ifndef STRING_H
#define STRING_H

#include <string.h>
#include <ctype.h>
#include <stdlib.h>
#ifndef WIN32
#include <sys/time.h>
#endif // WIN32
#ifdef WIN32
#include <winsock.h>
#endif // win32 to get the timeval struct */

#include <signal.h>
#define ASSERT( p ) if( !p ) raise( SIGSEGV )

#define BUF 4096

#define TAB 0x09

const char * ltoa( long );
inline const char * itoa( int x ) { return ltoa( (long)x ); }
const char * ultoa( unsigned long );
int str_cmp( const char *, const char * );
int str_abbrev( const char *, const char * );

class String;

class StringRep 
{
	private:
		friend class String;
		int count;
		int sz;       // actual size, strlen will return len
		char *str; 

		StringRep( )
		: count(1), sz(0), str(0) { }
		StringRep( const char * );
		StringRep( const StringRep & );
		StringRep( int );
		~StringRep( );
    
		const StringRep & operator = ( const StringRep & );
};


inline StringRep::StringRep( const char *x )
:	count( 1 ), sz( strlen(x)+1 ),
	str( new char[ strlen(x)+1 ] )
	{	strcpy( str, x );	}


inline StringRep::StringRep( const StringRep &orig )
:	count( 1 ), sz( strlen( orig.str ) + 1 ), str( new char[ sz ] )
	{	strcpy( str, orig.str );	}

inline StringRep::StringRep( int asize )
:	count( 1 ), sz( asize ), str( new char[ asize ] )
	{}

inline StringRep::~StringRep()
	{	delete [] str;	}


class String
{
	private:
		static StringRep * repEmpty;
		StringRep *rep;

	protected:
		// For startArgs(), getArg(), and getArgRest()
		static char _argbuf[ 1024 ];
		static char *_argptr;
		static char *_argnext;

	public:
		String();
		String( const char * );
		String( const String & );
		String( int );  
		~String();
   
		operator const char *() const { return rep->str; }
  
		int count() { return rep->count; } 
		int len() const;            // strlen
		void clr();		
		int size() const;              // size of allocated mem
		void allocate( int );          // explicitly allocate size mem
		const char * chars() const;
		char * dup() const;
		String asUpper() const;  
		String asLower() const;
		String asProper() const;
		String & ltrim();
		String & rtrim();
		String & strip( const char & );
		String & crypt( const String & salt );
		int asInt() const;
		bool isNumber() const;
		String & toUpper();  
		String & toLower();
		String & toProper();
		String & operator = ( const char * );
		String & operator = ( const String & ); 
		bool operator == ( const String & ) const;
		bool operator == ( const char * ) const;
		bool operator != ( const String & ) const;
		bool operator != ( const char * ) const;
		String & append( const String & );
		String & append( const String &, int );
		String & append( const char & );
		String & append( const char * );
		String & append( const char *, int );
		String & append( const timeval & );
		String & operator += ( const String & ); 
		String & operator += ( const char & ); 
		String & operator += ( const char * ); 
		String & operator += ( int ); 
		String & operator += ( unsigned long int );
		String operator + ( const String & ) const;
		String operator + ( const char * ) const;
		String operator + ( const char & ) const;
		String operator + ( int ) const;
		String operator + ( unsigned long ) const;
		operator bool() const { return (bool)*rep->str; }
		char & operator [] ( int i );
		const char & operator [] ( int i ) const;
		bool compare( const String & ) const;
		bool compare( const char * ) const;
		bool compareWithCase( const String & ) const;
		bool compareWithCase( const char * ) const;
		bool hasChar( const char & x ) const { return (bool)strchr( rep->str, x ); }
		bool isAbbrev( const String & ) const;
		bool isAbbrev( const char * ) const;
		bool hasAbbrev( const char * ) const;
		bool hasAbbrev( const String & ) const;
		String getLine( int ) const;
		String & operator << ( const char * );
		String & operator << ( const String & );
		String & operator << ( const char & );
		String & operator << ( short );
		String & operator << ( int );
		String & operator << ( long );
		String & operator << ( unsigned long );
		String & operator << ( float );
		String & operator << ( const timeval & );
		int sprintf( const char * fmt, ... );
		int sprintfAdd( const char * fmt, ... );
		void startArgs() const;
		String getArg() const;
		String getArgRest() const;
		void shiftLeft();
		void shiftRight();
		bool legalFilename() const;
};


inline String::String()
:	rep( repEmpty )
	{	rep->count++;	}

inline String::String( const char * s )
:	rep( new StringRep( s ) )
	{}

inline String::String( const String & x )
:	rep( x.rep )
	{	rep->count++;	}

inline String::String( int asize )
:	rep( new StringRep( asize ) )
	{	*rep->str = '\0';	}

inline String::~String()
{
	if( rep->count == 1 )
		delete rep;
	else rep->count--;
}

// This fixes the problem which arises in a lot of implementations
// when you do   if( "blah" == str ) and the const char * operator is
// invoked for the string object instead of the ==
inline bool operator == ( const char * ptr, const String & str )
{
	// Invoke string operator first.
	return str.compare( ptr );
}

inline const char * String::chars() const
	{	return rep->str;	 }

inline const char & String::operator[]( int i ) const
{
	if( i >= rep->sz )
		abort();
	return *(rep->str + i);
}

inline int String::len() const
	{	return strlen( rep->str );	}

inline int String::size() const
	{	return rep->sz;	}

inline String & String::append( const String & x )
	{	return append( x, strlen( x.chars() ) ); }

inline String & String::append( const char * x)
	{	return append( x, strlen( x ) ); }

inline String & String::operator += ( const String & x )
	{	return append( x );	}

inline String & String::operator += ( const char & x )
	{	return append( x );	}

inline String & String::operator += ( const char * x )
	{	return append( x );	}

inline String & String::operator += ( int x )
	{	return append( itoa( x ) );	}

inline String & String::operator += ( unsigned long x )
	{	return append( ltoa( x ) );	}

inline bool String::operator == ( const String & str ) const
	{	return compare( str );	}

inline bool String::operator == ( const char * str ) const
	{	return compare( str );	}

inline bool String::operator != ( const String & str ) const
	{	return !(compare( str ));	}

inline String & String::operator << ( const char * x )
	{	return append( x );	}

inline String & String::operator << ( const String & x )
	{	return append( x );	}

inline String & String::operator << ( const char & x )
	{	return append( x );	}

inline String & String::operator << ( int x )
	{	return append( itoa( x ) );	}

inline String & String::operator << ( short x )
	{	return append( itoa( (int) x ) );	}

inline String & String::operator << ( long x )
	{	return append( itoa( x ) );	}

inline String & String::operator << ( unsigned long x )
	{	return append( ltoa( x ) );	}

inline String & String::operator << ( const timeval & x )
	{	return append( x );	}

inline void String::startArgs() const
{
// Solaris ProWorks C++ does not support const_cast<> yet
//	strcpy( const_cast<String *>(this)->_argbuf, rep->str );
	strcpy( ((String *)this)->_argbuf, rep->str );
//	const_cast<String *>(this)->_argnext = _argbuf;
	((String *)this)->_argnext = _argbuf;
}

inline String String::getArgRest() const
	{	return String( _argnext );	}

inline int String::asInt() const
	{	return atoi( rep->str );	}

inline bool String::isAbbrev( const String & x ) const
	{	return isAbbrev( x.chars() );	}

inline bool String::hasAbbrev( const String & x ) const
	{	return hasAbbrev( x.chars() );	}

#endif