// 11/01/95 // String.h // // Header file for the String class. // // This is a string implementation which stores the data as both // a Pascal string (initial length byte) and a C string (null- // terminated array). While this introduces a few inefficencies, // it makes it very easy to use in a variety of circumstances. // // To make it more speed-efficient, at the expense of memory // efficiency, a fixed-length 256-byte buffer is allocated for // each string. This avoids deallocating/reallocating memory // whenever a string is reassigned. #ifndef STRING_H #define STRING_H #include #include #ifdef macintosh #include // for Str255 type (used for Toolbox calls) #endif #define itsChars itsData+1 #define itsLength itsData[0] #define StringInit itsData = new char[BUFSIZE]; itsData[0] = itsData[1] = 0 // BUFSIZE cannot be larger than 256 #define BUFSIZE 256 class String { protected: char *itsData; public: // constructors & destructor String( void ) { StringInit; } String( const String& pStr ) { StringInit; *this = pStr; } String( const char* pChars ) { StringInit; *this = pChars; } String( const int pInt ); // convert int to string ~String( void ) { delete itsData; }; // assignment operators String& operator= ( const String& pStr ); String& operator= ( const char* pChars ); // conversion operators & functions #ifdef macintosh String( const Str255 pPstr ) { StringInit; *this = pPstr; } String& operator= ( const Str255 pPstr ); operator unsigned char *(void) { return (unsigned char*)itsData; } operator ConstStr255Param(void) const { return (const unsigned char *)itsData; } #endif operator const char*(void) const { return itsChars; } friend int IntValue( const String& ); friend String Plural( const String& ); friend String Uppercase( const String& ); // comparison operators int operator== ( const String& s ) const { return strcmp(itsChars, s.itsChars) == 0; } int operator== ( const char* c ) const { return strcmp(itsChars, c) == 0; } int operator!= ( const String& s ) const { return strcmp(itsChars, s.itsChars) != 0; } int operator!= ( const char* c ) const { return strcmp(itsChars, c) != 0; } int operator> ( const String& s ) const { return strcmp(itsChars, s.itsChars) > 0; } int operator> ( const char* c ) const { return strcmp(itsChars, c) > 0; } int operator< ( const String& s ) const { return strcmp(itsChars, s.itsChars) < 0; } int operator< ( const char* c ) const { return strcmp(itsChars, c) < 0; } int operator>= ( const String& s ) const { return strcmp(itsChars, s.itsChars) >= 0; } int operator>= ( const char* c ) const { return strcmp(itsChars, c) >= 0; } int operator<= ( const String& s ) const { return strcmp(itsChars, s.itsChars) <= 0; } int operator<= ( const char* c ) const { return strcmp(itsChars, c) <= 0; } // concatenation, searching, substrings, etc. int Length(void) const { return (unsigned char)itsLength; } char& operator[] ( const int i ) const { return (i>=0 && i < Length() ? itsData[i+1] : itsData[1]); } int Index( const String& pSubstr ) const { char* c = strstr( itsChars, pSubstr.itsChars); return ( c ? c-(itsChars) : -1 ); } String Element( const int pElem, const char pDelim=' ' ) const; String Substr( const int from, const int to ) const; String operator() ( const int from, const int to ) const { return Substr(from,to); } String Left( const int qty=1 ) const { return Substr(0,qty-1); } String Right( const int qty=1 ) const { return Substr(Length()-qty,999); } String Trim() const; String& operator+= ( const String& s ); String& operator+= ( const char* c ); String operator+ ( const String& s2 ) const { String out(*this); out += s2; return out; } String operator+ ( const char* c ) const { String out(*this); out += c; return out; } String& operator*= ( const int times ) { String what(*this); for (int i=1; i>(istream& pStream, String& s ); inline istream& ReadLine(istream& pStream); // debugging void Dump( void ) const; }; inline ostream& operator<<(ostream& pStream, const String& s ) { return pStream << s.itsChars; } inline istream& operator>>(istream& pStream, String& s ) { pStream >> (char *)s.itsChars; s.itsLength = strlen(s.itsChars); return pStream; } inline istream& String::ReadLine(istream& pStream) { pStream.getline( itsChars, BUFSIZE-1 ); itsLength = strlen(itsChars); return pStream; } inline String Uppercase( const String& pStr ) { String out(pStr); for (char *c = out.itsChars; *c; c++) if (*c >= 'a' && *c <= 'z') *c -= ('a'-'A'); return out; } #undef itsChars #undef itsLength #endif