sin-sdk/str.h
1998-12-20 00:00:00 +00:00

460 lines
7.3 KiB
C++

//-----------------------------------------------------------------------------
//
// $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 <assert.h>
#include <string.h>
#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