Main Page   Modules   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

TString.cpp

Go to the documentation of this file.
00001 // TString.cpp: implementation of the TString class.
00004 
00005 
00006 #include "stdafx.h"
00007 #include "TString.h"
00008 
00010 // Macro Definitions
00012 
00017 #ifdef UNICODE
00018     #define TSTRING_BUFFERSIZE(length) ((int)(sizeof(WCHAR) * length))
00019 #else
00020     #define TSTRING_BUFFERSIZE(length) ((int)(length))
00021 #endif
00022 
00026 #define TSTRING_BUFFERLENGTHA(ansiString) (strlen(ansiString) + 1)
00027 
00031 #define TSTRING_BUFFERLENGTHW(unicodeString) (wcslen(unicodeString) + 1)
00032 
00034 // Construction/Destruction
00036 
00040 TString::TString()
00041 {
00042     bufferLength = 1;
00043     string = EMPTYSTRING;
00044 }
00045 
00049 TString::TString(const TString &copy)
00050 {
00051     bufferLength = 1;
00052     string = EMPTYSTRING;
00053     set(copy.get());
00054 }
00055 
00059 TString::TString(PCSTR ansiString)
00060 {
00061     bufferLength = 1;
00062     string = EMPTYSTRING;
00063     set(ansiString);
00064 }
00065 
00069 TString::TString(PCWSTR unicodeString)
00070 {
00071     bufferLength = 1;
00072     string = EMPTYSTRING;
00073     set(unicodeString);
00074 }
00075 
00079 TString::TString(const WCHAR unicodeChar)
00080 {
00081     bufferLength = 1;
00082     string = EMPTYSTRING;
00083     set(unicodeChar);
00084 }
00085 
00089 TString::TString(const CHAR ansiChar)
00090 {
00091     bufferLength = 1;
00092     string = EMPTYSTRING;
00093     set(ansiChar);
00094 }
00095 
00100 TString::TString(const int integer)
00101 {
00102     bufferLength = 1;
00103     string = EMPTYSTRING;
00104     set(integer);
00105 }
00106 
00107 
00111 TString::~TString()
00112 {
00113     memoryDealloc();
00114 }
00115 
00117 
00118 
00120 PTSTR TString::EMPTYSTRING = TEXT("");
00121 
00122 TString operator +( const TString& left, const TString& right)
00123 {
00124     // Length of right (less term) + this length (includes term)
00125     const int totalLength = left.bufferLength - 1 + right.bufferLength;
00126 
00127     TString rtrn;
00128 
00129     // Alloc sufficient memory
00130     assert( rtrn.alloc( totalLength ) );
00131 
00132     // Copy left to rtrn (inc term)
00133     assert( rtrn.stringCopy( left, left.bufferLength ) == left.bufferLength );
00134 
00135 #ifdef UNICODE
00136 
00137     wcscat( rtrn.string, right.string );
00138 
00139 #else
00140 
00141     strcat( rtrn.string, right.string );
00142 
00143 #endif
00144 
00145     return rtrn;
00146 }
00147 
00148 // The relience on the TString + TString operator by the following can 
00149 // easily be removed to improve perfomance.
00150 TString operator +( const TString& left, PCSTR right)
00151 {
00152     return left + TString(right);
00153 }
00154 
00155 TString operator +( const TString& left, PCWSTR right)
00156 {
00157     return left + TString(right);
00158 }
00159 
00160 TString operator +( PCSTR left, const TString& right)
00161 {
00162     return TString(left) + right;
00163 }
00164 
00165 TString operator +( PCWSTR left, const TString& right)
00166 {
00167     return TString(left) + right;
00168 }
00169 
00170 TString operator +( const TString& left, const WCHAR right)
00171 {
00172     return left + TString(right);
00173 }
00174 
00175 TString operator +( const TString& left, const CHAR right)
00176 {
00177     return left + TString(right);
00178 }
00179 
00180 TString operator +( const WCHAR left, const TString& right)
00181 {
00182     return TString(left) + right;
00183 }
00184 
00185 TString operator +( const CHAR left, const TString& right)
00186 {
00187     return TString(left) + right;
00188 }
00189 
00191 
00193 const TString &TString::operator=(const TString& right)
00194 {
00195     if(&right != this)
00196         set(right.get());
00197 
00198     return *this;
00199 }
00200 
00202 const TString &TString::operator=(PCSTR right)
00203 {
00204 #ifndef UNICODE
00205     // if native to ansi then it is possible that this is a self assignment 
00206     if(right == string)
00207         return *this;
00208 #endif
00209 
00210     set(right);
00211 
00212     return *this;
00213 }
00214 
00216 const TString &TString::operator=(PCWSTR right)
00217 {
00218 #ifdef UNICODE
00219     // if native to unicode then it is possible that this is a self assignment 
00220     if(right == string)
00221         return *this;
00222 #endif
00223 
00224     set(right);
00225 
00226     return *this;
00227 }
00228 
00230 const TString &TString::operator =(const CHAR ansiChar)
00231 {
00232     set(ansiChar);
00233     return *this;
00234 }
00235 
00237 const TString &TString::operator =(const WCHAR unicodeChar)
00238 {
00239     set(unicodeChar);
00240     return *this;
00241 }
00242 
00244 
00246 
00247 const TString& TString::operator +=( const TString& right )
00248 {
00249     TString left( *this );
00250 
00251     memoryDealloc();
00252 
00253     const int totalLength = left.bufferLength - 1 + right.bufferLength;
00254 
00255     assert( alloc( totalLength ) );
00256 
00257     assert( stringCopy ( left, left.bufferLength ) == left.bufferLength );
00258 
00259 #ifdef UNICODE
00260 
00261     wcscat( string, right.string );
00262 
00263 #else
00264 
00265     strcat( string, right.string );
00266 
00267 #endif
00268 
00269     return *this;
00270 }
00271 
00272 // The relience on the += TString operator by the following can 
00273 // easily be removed to improve perfomance.
00274 const TString& TString::operator +=( PCSTR right )
00275 {
00276     *this += TString(right);
00277     return *this;
00278 }
00279 
00280 const TString& TString::operator +=( PCWSTR right )
00281 {
00282     *this += TString(right);
00283     return *this;
00284 }
00285 
00286 const TString &TString::operator +=( const WCHAR right )
00287 {
00288     *this += TString(right);
00289     return *this;
00290 }
00291 
00292 const TString &TString::operator +=( const CHAR right )
00293 {
00294     *this += TString(right);
00295     return *this;
00296 }
00298 
00300 
00310 TCHAR TString::operator []( const int index ) const
00311 {
00312     if( index < 0 || index > bufferLength - 1 )
00313         RaiseException(EXCEPTION_ARRAY_BOUNDS_EXCEEDED, 0, 0, NULL);
00314 
00315     TCHAR rtrn = string[index];
00316     return rtrn;
00317 }
00318 
00324 bool TString::operator !() const
00325 {
00326     return bufferLength == 1;
00327 }
00328 
00330 
00339 bool TString::set(PCSTR ansiString)
00340 {
00341     if( ansiString == NULL ){
00342         clear();
00343         return true;
00344     }
00345 
00346     int ansiLength = TSTRING_BUFFERLENGTHA(ansiString);
00347 
00348     if( memoryAlloc(ansiString) == TSTRING_BUFFERSIZE(ansiLength) )
00349         return stringCopy(ansiString, ansiLength) == ansiLength;
00350     else
00351         return false;
00352 }
00353 
00362 bool TString::set(PCWSTR unicodeString)
00363 {
00364     if( unicodeString == NULL ){
00365         clear();
00366         return true;
00367     }
00368 
00369     int unicodeLength = TSTRING_BUFFERLENGTHW(unicodeString);
00370 
00371     if( memoryAlloc(unicodeString) == TSTRING_BUFFERSIZE(unicodeLength) )
00372         return stringCopy(unicodeString, unicodeLength) == unicodeLength;
00373     else
00374         return false;
00375 }
00376 
00384 bool TString::set(const CHAR ansiChar)
00385 {
00386     if( alloc(1+1) ){
00387         *(string + 1)  = TEXT('');
00388         return stringCopy(&ansiChar, 1) == 1;
00389     } else
00390         return false;
00391 }
00392 
00400 bool TString::set(const WCHAR unicodeChar)
00401 {
00402     if( alloc(1+1) ){
00403         *(string + 1)  = TEXT('');
00404         return stringCopy(&unicodeChar, 1) == 1;
00405     } else
00406         return false;
00407 }
00408 
00419 bool TString::set(const int integer)
00420 {
00421     TCHAR temp[12]; // temp: longest string needed to represent int
00422 
00423 #ifdef UNICODE
00424     swprintf(temp, L"%d", integer);
00425 #else
00426     sprintf(temp, "%d", integer);
00427 #endif 
00428 
00429     return set(temp);
00430 }
00431 
00433 
00440 PCTSTR TString::get() const
00441 {
00442     return string;
00443 }
00444 
00446 TString::clear()
00447 {
00448     memoryDealloc();
00449 }
00450 
00452 int TString::getBufferSize() const
00453 {
00454     return TSTRING_BUFFERSIZE(bufferLength);
00455 }
00456 
00458 int TString::getLength() const
00459 {
00460     return bufferLength - 1;
00461 }
00462 
00464 
00477 int TString::memoryAlloc(PCSTR ansiString, const bool allocate)
00478 {
00479     int length;
00480 
00481 #ifdef UNICODE
00482 
00483     // Calculate string length
00484     length = MultiByteToWideChar(
00485             CP_ACP,     // code page
00486             0,          // character-type options
00487             ansiString, // string to map
00488             -1,         // calculate number characters in string (inc terminator)
00489             NULL,       // wide-character buffer (not used yet)
00490             0);         // return size of required buffer in bytes
00491 
00492     if( !allocate || length == 0)
00493         return TSTRING_BUFFERSIZE(length);
00494 
00495 #else
00496 
00497     length = calculateTotalLength(ansiString);
00498 
00499     if( !allocate )
00500         return TSTRING_BUFFERSIZE(length);
00501 
00502 #endif
00503 
00504     memoryDealloc();
00505 
00506     if( alloc(length) )
00507         return TSTRING_BUFFERSIZE(bufferLength);
00508     else 
00509         return -1;
00510 
00511 }
00512 
00525 int TString::memoryAlloc(PCWSTR unicodeString, const bool allocate)
00526 {
00527     int length;
00528 
00529 #ifdef UNICODE
00530 
00531     length =  TSTRING_BUFFERLENGTHW(unicodeString);
00532 
00533     if( !allocate )
00534         return TSTRING_BUFFERSIZE(length);
00535 
00536 #else
00537 
00538     length = WideCharToMultiByte(
00539             CP_ACP,         // code page
00540             0,              // performance and mapping flags
00541             unicodeString,  // wide-character string
00542             -1,             // calculate number of chars in string
00543             NULL,           // buffer for new string (not used yet)
00544             0,              // return size of required buffer in bytes
00545             NULL,           // default for unmappable chars
00546             NULL);          // set when default char used
00547 
00548     if( !allocate || length == 0)
00549         return TSTRING_BUFFERSIZE(length);
00550 
00551 #endif    
00552 
00553     memoryDealloc();
00554 
00555     if( alloc(length) )
00556         return TSTRING_BUFFERSIZE(bufferLength);
00557     else 
00558         return -1;
00559 
00560 }
00561 
00567 bool TString::alloc(const int length)
00568 {
00569     // Allocate memory
00570     string = new TCHAR[TSTRING_BUFFERSIZE(length)];
00571     // Check Allocation
00572     if ( string == NULL ){
00573         bufferLength = 1;
00574         string = EMPTYSTRING;
00575         return false;
00576     } else {
00577         bufferLength = length;
00578         return true;
00579     }
00580 }
00581 
00588 TString::memoryDealloc()
00589 {
00590     if( string != EMPTYSTRING ){
00591         delete [] string;
00592         string = EMPTYSTRING;
00593         bufferLength = 1;
00594     }
00595 }
00596 
00602 int TString::stringCopy(PCSTR ansiString, const int length)
00603 {
00604 #ifdef UNICODE
00605 
00606     // Convert ANSI to Unicode
00607     return MultiByteToWideChar(CP_ACP, 0, ansiString, length, string, TSTRING_BUFFERSIZE(bufferLength));
00608 
00609 #else
00610 
00611     int ansiLength = length;
00612     if( ansiLength < 0 ){
00613         ansiLength = calculateTotalLength(ansiString);
00614     }
00615 
00616     __try{
00617         CopyMemory(string, ansiString, TSTRING_BUFFERSIZE(ansiLength));
00618     }
00619     __except( (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION) 
00620             ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
00621         return -1;
00622     }
00623     
00624     return ansiLength;
00625 
00626 #endif
00627 }
00628 
00634 int TString::stringCopy(PCWSTR unicodeString, const int length)
00635 {
00636 #ifdef UNICODE
00637 
00638     int unicodeLength = length;
00639     if( unicodeLength < 0 ){
00640         unicodeLength = TSTRING_BUFFERLENGTHW(unicodeString);
00641     }
00642 
00643     __try{
00644         CopyMemory(string, unicodeString, TSTRING_BUFFERSIZE(unicodeLength));
00645     }
00646     __except( (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION) 
00647             ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
00648         return -1;
00649     }
00650     
00651     return unicodeLength;
00652 
00653 #else
00654 
00655     // Convert Unicode to ANSI
00656     return WideCharToMultiByte(CP_ACP,  0, unicodeString, length, string, TSTRING_BUFFERSIZE(bufferLength), NULL, NULL);
00657 
00658 #endif
00659 }

Generated on Mon Mar 25 06:29:59 2002 for Window Dressing by doxygen1.2.13.1 written by Dimitri van Heesch, © 1997-2001