460 lines
7.3 KiB
C++
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
|