00001
00004
00005
00006 #include "stdafx.h"
00007 #include "TString.h"
00008
00010
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
00036
00040 TString::TString()
00041 {
00042 bufferLength = 1;
00043 string = EMPTYSTRING;
00044 }
00045
00049 TString::TString(const TString ©)
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
00125 const int totalLength = left.bufferLength - 1 + right.bufferLength;
00126
00127 TString rtrn;
00128
00129
00130 assert( rtrn.alloc( totalLength ) );
00131
00132
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
00149
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
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
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
00273
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];
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
00484 length = MultiByteToWideChar(
00485 CP_ACP,
00486 0,
00487 ansiString,
00488 -1,
00489 NULL,
00490 0);
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,
00540 0,
00541 unicodeString,
00542 -1,
00543 NULL,
00544 0,
00545 NULL,
00546 NULL);
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
00570 string = new TCHAR[TSTRING_BUFFERSIZE(length)];
00571
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
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
00656 return WideCharToMultiByte(CP_ACP, 0, unicodeString, length, string, TSTRING_BUFFERSIZE(bufferLength), NULL, NULL);
00657
00658 #endif
00659 }