/* ....[@@@..[@@@..............[@.................. 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