Initial commit.
This commit is contained in:
366
code/ratl/string_vs.h
Normal file
366
code/ratl/string_vs.h
Normal file
@@ -0,0 +1,366 @@
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// RAVEN STANDARD TEMPLATE LIBRARY
|
||||
// (c) 2002 Activision
|
||||
//
|
||||
//
|
||||
// String
|
||||
// ------
|
||||
// Simple wrapper around a char[SIZE] array.
|
||||
//
|
||||
//
|
||||
//
|
||||
// NOTES:
|
||||
//
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
#if !defined(RATL_STRING_VS_INC)
|
||||
#define RATL_STRING_VS_INC
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Includes
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
#if !defined(RATL_COMMON_INC)
|
||||
#include "ratl_common.h"
|
||||
#endif
|
||||
|
||||
namespace ratl
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// The String Class
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
template<int ARG_CAPACITY>
|
||||
class string_vs : public ratl_base
|
||||
{
|
||||
public:
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Capacity Enum
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
enum
|
||||
{
|
||||
CAPACITY = ARG_CAPACITY,
|
||||
};
|
||||
private:
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Data
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
#ifdef _DEBUG
|
||||
char mData[CAPACITY+4];
|
||||
#else
|
||||
char mData[CAPACITY];
|
||||
#endif
|
||||
|
||||
void FillTerminator()
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
mData[CAPACITY]='e';
|
||||
mData[CAPACITY+1]='n';
|
||||
mData[CAPACITY+2]='d';
|
||||
mData[CAPACITY+3]=0;
|
||||
#endif
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Constructor
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
string_vs()
|
||||
{
|
||||
mData[0]=0;
|
||||
FillTerminator();
|
||||
}
|
||||
#ifdef _DEBUG
|
||||
~string_vs()
|
||||
{
|
||||
//if you hit the below asserts, the end of the string was overwritten
|
||||
assert(mData[CAPACITY]=='e');
|
||||
assert(mData[CAPACITY+1]=='n');
|
||||
assert(mData[CAPACITY+2]=='d');
|
||||
assert(mData[CAPACITY+3]==0);
|
||||
}
|
||||
#endif
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Copy Constructor
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
string_vs(const string_vs<CAPACITY> &o)
|
||||
{
|
||||
assert(str::len(o.mData)<CAPACITY);
|
||||
str::ncpy(mData, o.mData, CAPACITY); // Safe String Copy
|
||||
mData[CAPACITY-1] = 0; // Make Sure We Have A Null Terminated Str
|
||||
FillTerminator();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Copy Constructor
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
string_vs(const char *s)
|
||||
{
|
||||
assert(str::len(s)<CAPACITY);
|
||||
str::ncpy(mData, s, CAPACITY); // Safe String Copy
|
||||
mData[CAPACITY-1] = 0; // Make Sure We Have A Null Terminated Str
|
||||
FillTerminator();
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
string_vs& operator=(const char *s)
|
||||
{
|
||||
assert(str::len(s)<CAPACITY);
|
||||
str::ncpy(mData, s, CAPACITY); // Safe String Copy
|
||||
mData[CAPACITY-1] = 0; // Make Sure We Have A Null Terminated Str
|
||||
FillTerminator();
|
||||
return *this;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Access To Raw Array
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
char* c_str()
|
||||
{
|
||||
return mData;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Access To Raw Array
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
const char* c_str() const
|
||||
{
|
||||
return mData;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Access To Raw Array
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
operator const char *()
|
||||
{
|
||||
return mData;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Access To Raw Array
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
const char* operator*()
|
||||
{
|
||||
return mData;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// How Many Characters Can This Hold
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
int capacity() const
|
||||
{
|
||||
return CAPACITY;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Length
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
int length() const
|
||||
{
|
||||
assert(str::len(mData)<CAPACITY-1);
|
||||
return str::len(mData);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Character Bracket Operator
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
char operator[](int index)
|
||||
{
|
||||
assert(index<CAPACITY);
|
||||
return mData[index];
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Equality Operator
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
bool operator==(const string_vs &o) const
|
||||
{
|
||||
if (!stricmp(mData,o.mData))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// InEquality Operator
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
bool operator!=(const string_vs &o) const
|
||||
{
|
||||
if (str::icmp(mData,o.mData)!=0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Compare Less Than
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
bool operator<(const string_vs &o) const
|
||||
{
|
||||
if (str::icmp(mData,o.mData)<0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Compare Greater Than
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
bool operator>(const string_vs &o) const
|
||||
{
|
||||
if (str::icmp(mData,o.mData)>0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
void operator+=(const string_vs &o)
|
||||
{
|
||||
if ( (str::len(mData)+o.length())<CAPACITY ) // Only If It Is Safe
|
||||
{
|
||||
str::cat(mData, o.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(!"string_vs overflow\n");
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
void operator+=(const char *s)
|
||||
{
|
||||
if ( (str::len(mData)+str::len(s))<CAPACITY ) // Only If It Is Safe
|
||||
{
|
||||
str::cat(mData, s);
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(!"string_vs overflow\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Tokenizer
|
||||
//
|
||||
// The string tokenizer class is similar to an iterator in that it essentially
|
||||
// iterates over all the tokens in the string seperated by a common series of
|
||||
// delinating sequences. For example: " ,\t\n" would seperate tokens on spaces
|
||||
// commas, tabs and linefeeds.
|
||||
//
|
||||
// Iterating over string tokens is just like normal iteration:
|
||||
//
|
||||
// for (string_vs<CAPACITY>::tokenizer it=MyString.begin(" ,\t\n"); it!=MyString.end(); it++)
|
||||
// {
|
||||
// const char* token = *it;
|
||||
// }
|
||||
//
|
||||
//
|
||||
// NOTE: This class is built upon the c library function strtok() which uses a
|
||||
// static working area, so having multiple tokenizers in multiple threads or just
|
||||
// plain at the same time is not safe.
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
class tokenizer
|
||||
{
|
||||
enum
|
||||
{
|
||||
TOKEN_GAP_LEN = 15,
|
||||
};
|
||||
|
||||
public:
|
||||
// Constructors
|
||||
//--------------
|
||||
tokenizer() : mLoc(0)
|
||||
{}
|
||||
tokenizer(const char* t, const char* gap)
|
||||
{
|
||||
strncpy(mGap, gap, TOKEN_GAP_LEN); // Safe String Copy
|
||||
mGap[TOKEN_GAP_LEN-1] = 0; // Make Sure We Have A Null Terminated Str
|
||||
|
||||
char* temp = (char*)t;
|
||||
mLoc = str::tok(temp, mGap);
|
||||
}
|
||||
|
||||
// Assignment Operator
|
||||
//---------------------
|
||||
void operator= (const tokenizer &t)
|
||||
{
|
||||
mLoc = t.mLoc;
|
||||
str::cpy(mGap, t.mGap);
|
||||
}
|
||||
|
||||
// Equality Operators
|
||||
//--------------------
|
||||
bool operator==(const tokenizer &t) {return (mLoc==t.mLoc);}
|
||||
bool operator!=(const tokenizer &t) {return !(operator==(t));}
|
||||
|
||||
|
||||
|
||||
// DeReference Operator
|
||||
//----------------------
|
||||
const char* operator*()
|
||||
{
|
||||
assert(mLoc);
|
||||
return mLoc;
|
||||
}
|
||||
|
||||
// Inc & Dec Operators
|
||||
//--------------------
|
||||
void operator++(int)
|
||||
{
|
||||
assert(mLoc && mGap[0]);
|
||||
mLoc = str::tok(NULL, mGap);
|
||||
}
|
||||
|
||||
// Data
|
||||
//------
|
||||
private:
|
||||
char* mLoc;
|
||||
char mGap[TOKEN_GAP_LEN];
|
||||
};
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Get An Iterator To The First Token Seperated By Gap
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
tokenizer begin(const char* gap)
|
||||
{
|
||||
return tokenizer(mData, gap);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// The Invalid Iterator, Use As A Stop Condition In Your For Loops
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
tokenizer end()
|
||||
{
|
||||
return tokenizer();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
//fixme get rid of these
|
||||
typedef ratl::string_vs<256> TString_vs;
|
||||
typedef ratl::string_vs<128> TUIString_vs;
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user