//----------------------------------------------------------------------------- // // $Logfile:: /Quake 2 Engine/Sin/code/game/str.h $ // $Revision:: 6 $ // $Author:: Jimdose $ // $Date:: 10/25/98 11:58p $ // // Copyright (C) 1997 by Ritual Entertainment, Inc. // All rights reserved. // // This source is may not be distributed and/or modified without // expressly written permission by Ritual Entertainment, Inc. // // $Log:: /Quake 2 Engine/Sin/code/game/str.h $ // // 6 10/25/98 11:58p Jimdose // working on getting rid of exports // // 5 10/08/98 12:04a Jimdose // made = keep the old string around until it was copied in case the source was // inside the old string // // 4 6/09/98 4:25p Jimdose // added substring copy constructor // // 3 5/13/98 4:53p Jimdose // Moved defintion of functions to header to make them inline // // 2 4/30/98 9:23p Jimdose // Created file // // DESCRIPTION: // Simple, DLL portable string class // #ifndef __STR_H__ #define __STR_H__ #include #include #if 1 class __declspec( dllexport ) str #else class str #endif { protected: int len; char *data; public: ~str(); str(); str( const char *text ); str( const str& string ); str( const str string, int start, int end ); int length( void ) const; const char * c_str( void ) const; void append( const char *text ); void append( const str& text ); char operator[]( int index ) const; char& operator[]( int index ); void operator=( const str& text ); void operator=( const char *text ); friend str operator+( const str& a, const str& b ); friend str operator+( const str& a, const char *b ); friend str operator+( const char *a, const str& b ); str& operator+=( const str& a ); str& operator+=( const char *a ); friend int operator==( const str& a, const str& b ); friend int operator==( const str& a, const char *b ); friend int operator==( const char *a, const str& b ); friend int operator!=( const str& a, const str& b ); friend int operator!=( const str& a, const char *b ); friend int operator!=( const char *a, const str& b ); }; inline str::~str() { assert( data ); if ( data ) { delete [] data; data = NULL; } } inline str::str() { data = new char[ 1 ]; data[ 0 ] = 0; len = 0; } inline str::str ( const char *text ) { assert( text ); if ( text ) { len = strlen( text ); data = new char[ len + 1 ]; strcpy( data, text ); } else { data = new char[ 1 ]; data[ 0 ] = 0; len = 0; } } inline str::str ( const str& text ) { len = text.length(); data = new char[ len + 1 ]; strcpy( data, text.c_str() ); } inline str::str ( const str text, int start, int end ) { int i; if ( end > text.length() ) { end = text.length(); } if ( start > text.length() ) { start = text.length(); } len = end - start; if ( len < 0 ) { len = 0; } data = new char[ len + 1 ]; for( i = 0; i < len; i++ ) { data[ i ] = text[ start + i ]; } data[ len ] = 0; } inline int str::length( void ) const { return len; } inline const char *str::c_str( void ) const { assert( data ); return data; } inline void str::append ( const char *text ) { char *olddata; assert( text ); assert( data ); if ( text ) { olddata = data; len = strlen( data ) + strlen( text ); data = new char[ len + 1 ]; strcpy( data, olddata ); strcat( data, text ); if ( olddata ) { delete [] olddata; olddata = NULL; } } } inline void str::append ( const str& text ) { assert( data ); append( text.c_str() ); } inline char str::operator[]( int index ) const { assert( data ); // don't include the '/0' in the test, because technically, it's out of bounds assert( ( index >= 0 ) && ( index < len ) ); // In release mode, give them a null character // don't include the '/0' in the test, because technically, it's out of bounds if ( ( index < 0 ) || ( index >= len ) ) { return 0; } return data[ index ]; } inline char& str::operator[] ( int index ) { // Used for result for invalid indices static char dummy = 0; assert( data ); // don't include the '/0' in the test, because technically, it's out of bounds assert( ( index >= 0 ) && ( index < len ) ); // In release mode, let them change a safe variable // don't include the '/0' in the test, because technically, it's out of bounds if ( ( index < 0 ) || ( index >= len ) ) { return dummy; } return data[ index ]; } inline void str::operator= ( const str& text ) { char *temp; assert( data ); len = text.length(); temp = new char[ len + 1 ]; strcpy( temp, text.c_str() ); // we don't destroy the old data until we've allocated the new one // in case we are assigning the string from data inside the old string. if ( data ) { delete [] data; } data = temp; } inline void str::operator= ( const char *text ) { char *temp; assert( data ); assert( text ); if ( !text ) { // safe behaviour if NULL len = 0; temp = new char[ 1 ]; temp[ 0 ] = 0; } else { len = strlen( text ); temp = new char[ len + 1 ]; strcpy( temp, text ); } // we don't destroy the old data until we've allocated the new one // in case we are assigning the string from data inside the old string. if ( data ) { delete [] data; } data = temp; } inline str operator+ ( const str& a, const str& b ) { str result( a ); result.append( b ); return result; } inline str operator+ ( const str& a, const char *b ) { str result( a ); result.append( b ); return result; } inline str operator+ ( const char *a, const str& b ) { str result( a ); result.append( b ); return result; } inline str& str::operator+= ( const str& a ) { assert( data ); append( a ); return *this; } inline str& str::operator+= ( const char *a ) { assert( data ); append( a ); return *this; } inline int operator== ( const str& a, const str& b ) { return ( !strcmp( a.c_str(), b.c_str() ) ); } inline int operator== ( const str& a, const char *b ) { assert( b ); if ( !b ) { return false; } return ( !strcmp( a.c_str(), b ) ); } inline int operator== ( const char *a, const str& b ) { assert( a ); if ( !a ) { return false; } return ( !strcmp( a, b.c_str() ) ); } inline int operator!= ( const str& a, const str& b ) { return !( a == b ); } inline int operator!= ( const str& a, const char *b ) { return !( a == b ); } inline int operator!= ( const char *a, const str& b ) { return !( a == b ); } // Test function void TestStringClass( void ); #endif