Main Page   Namespace List   Class Hierarchy   Compound List   File List   Compound Members   File Members  

StdString.cpp

Go to the documentation of this file.
00001 /*
00002  * Filename                     : stcl_string.cpp

00003  *
00004  * Description          : String class implementation

00005  *
00006  * (c) 1999 Tough Cookie Productions.

00007  *
00008  * <insert your favorite legal blah blah here>

00009  *
00010  */
00011 
00012 
00013 #include <stdio.h>
00014 #include <stdarg.h>
00015 #include "StdString.h"
00016 
00017 /*-------------------------------------------------------------------------------------------------

00018         Construction / destruction

00019 -------------------------------------------------------------------------------------------------*/
00020 
00021 
00022 
00023 //
00024 // Construct an empty string
00025 //
00026 CCString::CCString() : 
00027         pData(new char [32]), 
00028         Len(0), 
00029         Max(32)
00030 {
00031         pData[0] = 0;
00032 }
00033 
00034 
00035 
00036 //
00037 // Construct a string of one character
00038 //
00039 CCString::CCString(char c) :
00040         pData(new char [9]),
00041         Len(1),
00042         Max(9)
00043 {
00044         pData[0] = c;
00045         pData[1] = 0;
00046 }
00047 
00048 
00049 
00050 //
00051 // Construct a string of multiple repeating characters
00052 //
00053 CCString::CCString(char c, int len) :
00054         pData(new char [len+8]),
00055         Len(len),
00056         Max(len+8)
00057 {
00058         assertd(pData != NULL);
00059         memset(pData, c, len);
00060         pData[len] = 0;
00061 }
00062 
00063 
00064 
00065 //
00066 // Construct a string from a pointer-to-ASCIIZ-string
00067 //
00068 CCString::CCString(const char *str) :
00069         pData(new char [strlen(str)+8]),
00070         Len(strlen(str)),
00071         Max(strlen(str)+8)
00072 {
00073         assertd(pData != NULL);
00074         memcpy(pData, str, strlen(str));
00075         pData[strlen(str)] = 0;
00076 }
00077 
00078 
00079 
00080 //
00081 // Construct a string from a pointer-to-ASCII-string and a length
00082 //
00083 CCString::CCString(const char *str, int len) :
00084         pData(new char [len+8]),
00085         Len(len),
00086         Max(len+8)
00087 {
00088         assertd(pData != NULL);
00089         memcpy(pData, str, len);
00090         pData[len] = 0;
00091 }
00092 
00093 
00094 
00095 //
00096 // Construct a string from another string
00097 //
00098 CCString::CCString(rcCCString str) :
00099         pData(new char [str.Length()+8]),
00100         Len(str.Length()),
00101         Max(str.Length()+8)
00102 {
00103         assertd(pData != NULL);
00104         assertd(str.pData != NULL);
00105         memcpy(pData, str.pData, str.Length());
00106         pData[str.Length()] = 0;
00107 }
00108 
00109 
00110 
00111 //
00112 // Construct a string from the first number of characters in another string
00113 //
00114 CCString::CCString(rcCCString str, int len) :
00115         pData(new char [len+8]),
00116         Len(len),
00117         Max(len+8)
00118 {
00119         assertd(pData != NULL);
00120         assertd(str.pData != NULL);
00121         memcpy(pData, str.pData, str.Length());
00122         pData[str.Length()] = 0;
00123 }
00124 
00125 
00126 
00127 //
00128 // Create a string by concatenating two sources
00129 //
00130 CCString::CCString(const char *src1, int len1, const char *src2, int len2) :
00131         pData(new char [len1+len2+8]),
00132         Len(len1+len2),
00133         Max(len1+len2+8)
00134 {
00135         assertd(pData != NULL);
00136         memcpy(pData, src1, len1);
00137         memcpy(pData+len1, src2, len2);
00138         pData[len1+len2] = 0;
00139 }
00140 
00141 
00142 
00143 //
00144 // Create a string with an integer value
00145 //
00146 CCString::CCString(int val) :
00147         pData(new char [32]),
00148         Max(32)
00149 {
00150         assertd(pData != NULL);
00151         Len=sprintf(pData, "%d", val);
00152 }
00153         
00154 
00155 
00156 
00157 //
00158 // Create a string with a dword value
00159 //
00160 CCString::CCString(dword val) :
00161         pData(new char [32]),
00162         Max(32)
00163 {
00164         assertd(pData != NULL);
00165         Len=sprintf(pData, "%u", val);
00166 }
00167 
00168 
00169 
00170 //
00171 // Create a string with a floating point value
00172 //
00173 CCString::CCString(float val) :
00174         pData(new char [32]),
00175         Max(32)
00176 {
00177         assertd(pData != NULL);
00178         Len=sprintf(pData, "%g", val);
00179 }
00180 
00181 
00182 
00183 //
00184 // Create a string with a double value
00185 //
00186 CCString::CCString(double val) :
00187         pData(new char [32]),
00188         Max(32)
00189 {
00190         assertd(pData != NULL);
00191         Len=sprintf(pData, "%g", val);
00192 }
00193 
00194 
00195 
00196 /*-------------------------------------------------------------------------------------------------

00197         Buffer management

00198 -------------------------------------------------------------------------------------------------*/
00199 
00200 
00201 
00202 //
00203 // Make sure that the allocated buffer is at least <len> in size
00204 //
00205 void CCString::AllocBuffer(int len, bool keep_contents)

00206 {
00207         // Check if we have enough space
00208         if (len+1 <= Max) return;
00209 
00210         // Reallocate string
00211         char *new_data = new char [len+8];
00212         if (keep_contents) memcpy(new_data, pData, Len);
00213         delete[] pData;
00214 
00215         // Accept new data
00216         Max = len+8;
00217         pData = new_data;
00218         assertd(pData != NULL);
00219 }
00220         
00221 
00222 
00223 /*-------------------------------------------------------------------------------------------------

00224         Basic string operations

00225 -------------------------------------------------------------------------------------------------*/
00226 
00227 
00228 
00229 //
00230 // Format string (as does sprintf)
00231 //
00232 CCString& CCString::Format(const char *fmt, ...)

00233 {
00234         AllocBuffer(2048, false);
00235 
00236         assertd(pData != NULL);
00237         // Expand arguments and format to string
00238         va_list args;
00239         va_start(args, fmt);
00240         Len = vsprintf(pData, fmt, args);
00241         assertd(Len <= 2048);
00242         va_end(args);
00243 
00244         return *this;
00245 }
00246 
00247 
00248 
00249 //
00250 // Format string (as does sprintf)
00251 //
00252 CCString& CCString::FormatAdd(const char *fmt, ...)

00253 {
00254         AllocBuffer(2048, false);
00255 
00256         assertd(pData != NULL);
00257         // Expand arguments and format to string
00258         va_list args;
00259         va_start(args, fmt);
00260         Len += vsprintf(pData+Len, fmt, args);
00261         assertd(Len <= 2048);
00262         va_end(args);
00263 
00264         return *this;
00265 }
00266 
00267 
00268 
00269 /*-------------------------------------------------------------------------------------------------

00270         Properties

00271 -------------------------------------------------------------------------------------------------*/
00272 
00273 
00274 
00275 //
00276 // Check if string is entirely in UPPERCase
00277 //
00278 bool CCString::IsUpper() const

00279 {
00280         for (int i=0; i<Len; i++)
00281                 if (isLower(pData[i]))
00282                         return false;
00283 
00284         return true;
00285 }
00286 
00287 
00288 
00289 //
00290 // Check if string is entirely in lowerCase
00291 //
00292 bool CCString::IsLower() const

00293 {
00294         for (int i=0; i<Len; i++)
00295                 if (isUpper(pData[i]))
00296                         return false;
00297 
00298         return true;
00299 }
00300 
00301 
00302 
00303 /*-------------------------------------------------------------------------------------------------

00304         Search/Replace

00305 -------------------------------------------------------------------------------------------------*/
00306 
00307 
00308 
00309 //
00310 // Find the first orccurence of <c> in the string
00311 //
00312 int CCString::Find(char c, int pos) const

00313 {
00314         assertd(pos >= 0);
00315         assertd(Len==0 || pos<Len);
00316         assertd(pData != NULL);
00317         char *find_pos = strchr(pData+pos, c);
00318         return (find_pos) ? (find_pos-pData) : -1;
00319 }
00320 
00321 
00322 
00323 //
00324 // Find the first occurence of <str> in the string
00325 //
00326 int     CCString::Find(const char *str, int pos) const

00327 {
00328         assertd(pos >= 0);
00329         assertd(Len==0 || pos<Len);
00330         assertd(pData != NULL);
00331         char *find_pos = strstr(pData+pos, str);
00332         return (find_pos) ? (find_pos-pData) : -1;
00333 }
00334 
00335 
00336 
00337 //
00338 // Find the first occurence of <str> in the string
00339 //
00340 int     CCString::Find(rcCCString str, int pos) const

00341 {
00342         assertd(pos >= 0);
00343         assertd(Len==0 || pos<Len);
00344         assertd(pData != NULL);
00345         char *find_pos = strstr(pData+pos, str.ReadPtr());
00346         return (find_pos) ? (find_pos-pData) : -1;
00347 }
00348 
00349 
00350 
00351 //
00352 // Find the last occurence of <c> in the string
00353 //
00354 int CCString::RFind(char c) const

00355 {
00356         assertd(pData != NULL);
00357         char *pos = strrchr(pData, c);
00358         return (pos) ? (pos-pData) : -1;
00359 }
00360 
00361 
00362 
00363 //
00364 // Find the first occurence of any character in character set <set> in the string
00365 //
00366 int CCString::FindOneOf(const char *set, int pos) const

00367 {
00368         assertd(pos >= 0);
00369         assertd(Len==0 || pos<Len);
00370         assertd(pData != NULL);
00371         char *find_pos = strpbrk(pData+pos, set);
00372         return (find_pos) ? (find_pos-pData) : -1;
00373 }
00374 
00375 
00376 
00377 //
00378 // Replace a character in this string with another string
00379 //
00380 void CCString::Replace(int pos, rcCCString str)

00381 {
00382         //bounds(pos, 0, Length()-1);
00383 
00384         if (str.Length() < 1)
00385         {
00386                 // Remove one character from the string
00387                 memcpy(pData+pos, pData+pos+1, Len-pos);
00388         }
00389         else
00390         {
00391                 // Insert zero or more characters into the string
00392                 AllocBuffer(Len + str.Length() - 1, true);
00393                 if (str.Length() != 1) memcpy(pData+pos+str.Length(), pData+pos+1, Length()-pos);
00394                 memcpy(pData+pos, str.ReadPtr(), str.Length());
00395         }
00396 
00397         Len += str.Length()-1;
00398 }
00399 
00400 
00401 
00402 //
00403 // Replace a substring of this string with another string
00404 //
00405 void CCString::Replace(int pos, int num, rcCCString str)

00406 {
00407         //bounds(pos, 0, Length()-1);
00408         //bounds(pos+num, 0, Length());
00409         assertd(num >= 1);
00410 
00411         if (str.Length() < num)
00412         {
00413                 // Remove some data from the string by replacement
00414                 memcpy(pData+pos+str.Length(), pData+pos+num, Len-pos-num+1);
00415                 memcpy(pData+pos, str.ReadPtr(), str.Length());
00416         }
00417         else
00418         {
00419                 // Insert zero or more characters into the string
00420                 AllocBuffer(Len + str.Length() - num, true);
00421                 if (str.Length() != num) memcpy(pData+pos+str.Length(), pData+pos+num, Length()-pos-num+1);
00422                 memcpy(pData+pos, str.ReadPtr(), str.Length());
00423         }
00424 
00425         Len += str.Length()-num;
00426 }
00427 
00428 
00429 
00430 /*-------------------------------------------------------------------------------------------------

00431         Comparison

00432 -------------------------------------------------------------------------------------------------*/
00433 
00434 
00435 
00436 //
00437 // Compare two strings and return the result, <0 if *this<rhs, >0 if *this>rhs or 0 if *this==rhs
00438 //
00439 int     CCString::Compare(rcCCString rhs) const

00440 {
00441         return strcmp(pData, rhs.pData);
00442 }
00443 
00444 
00445 
00446 //
00447 // Compare two strings without respecting case and return the result, <0 if *this<rhs, >0 if *this>rhs or 0 if *this==rhs
00448 //
00449 int CCString::CompareNoCase(rcCCString rhs) const

00450 {
00451 #ifdef _WIN32
00452         return stricmp(pData, rhs.pData);
00453 #else
00454         return strcasecmp(pData, rhs.pData);
00455 #endif
00456 }
00457 
00458 
00459 
00460 /*-------------------------------------------------------------------------------------------------

00461         Formatting

00462 -------------------------------------------------------------------------------------------------*/
00463 
00464 
00465 
00466 //
00467 // Capitalize string, "heLLo" -> "HELLO"
00468 //
00469 CCString&       CCString::Upper()

00470 {
00471         assertd(pData != NULL);
00472 #ifdef _WIN32
00473         _strupr(pData);
00474 #else
00475         for (int i=0;i<Len;i++)
00476                 pData[i] = (pData[i] >= 'a' && pData[i] <= 'z')?pData[i]+'A'-'a':pData[i];
00477 #endif
00478         return *this;
00479 }
00480 
00481 
00482 
00483 //
00484 // Lower string, "heLLo" -> "hello"
00485 //
00486 CCString&       CCString::Lower()

00487 {
00488         assertd(pData != NULL);
00489 #ifdef _WIN32
00490         _strlwr(pData);
00491 #else
00492         for (int i=0;i<Len;i++)
00493                 pData[i] = (pData[i] >= 'A' && pData[i] <= 'Z')?pData[i]+'a'-'A':pData[i];
00494 #endif
00495         return *this;
00496 }
00497 
00498 
00499 
00500 //
00501 // Capitalize string, "heLLo" -> "Hello"
00502 //
00503 CCString&       CCString::Capitalize()

00504 {
00505         assertd(pData != NULL);
00506 #ifdef _WIN32
00507         if (Len>0) pData[0] = toupper(pData[0]);
00508         if (Len>1) _strlwr(pData+1);
00509 #else
00510         if (Len > 0)
00511                 pData[0] = (pData[0] >= 'A' && pData[0] <= 'A')?pData[0]+'a'-'A':pData[0];
00512         for (int i=1;i<Len;i++)
00513                 pData[i] = (pData[i] >= 'a' && pData[i] <= 'z')?pData[i]+'A'-'a':pData[i];
00514 #endif
00515         return *this;
00516 }
00517 
00518 
00519 
00520 //
00521 // Trim whitespace from the left side of the string
00522 //
00523 CCString&       CCString::TrimLeft()

00524 {
00525         int skip;
00526         assertd(pData != NULL);
00527         for (skip=0; isSpace(pData[skip]); skip++, Len--);
00528         memmove(pData, pData+skip, Len+1);
00529         return *this;
00530 }
00531 
00532 
00533 
00534 //
00535 // Trim whitespaces from the right side of the string
00536 //
00537 CCString&       CCString::TrimRight()

00538 {
00539         assertd(pData != NULL);
00540         while (Len && isSpace(pData[Len-1])) Len--;
00541         pData[Len]=0;
00542         return *this;
00543 }
00544 
00545 
00546 
00547 //
00548 // Trim spaces from both sides of the character set
00549 //
00550 CCString&       CCString::Trim()

00551 {
00552         TrimRight();
00553         TrimLeft();
00554         return *this;
00555 }
00556 
00557 
00558 
00559 //
00560 // Trim characters from the character set <set> from the left side of the string
00561 //
00562 CCString&       CCString::TrimLeft(char *set)

00563 {
00564         int skip;
00565         assertd(pData != NULL);
00566         for (skip=0; Len && strchr(set, pData[skip]); skip++, Len--);
00567         memmove(pData, pData+skip, Len+1);
00568         return *this;
00569 }
00570 
00571 
00572 
00573 //
00574 // Trim characters from the character set <set> from the right side of the string
00575 //
00576 CCString&       CCString::TrimRight(char *set)

00577 {
00578         assertd(pData != NULL);
00579         while (Len && strchr(set, pData[Len-1])) Len--;
00580         pData[Len]=0;
00581         return *this;
00582 }
00583 
00584 
00585 
00586 //
00587 // Trim characters from the character set <set> from both sides of the character set
00588 //
00589 CCString&       CCString::Trim(char *set)

00590 {
00591         TrimRight(set);
00592         TrimLeft(set);
00593         return *this;
00594 }
00595 
00596 
00597 
00598 //
00599 // Trim quotes from both sides of the string
00600 //
00601 CCString&       CCString::TrimQuotes()

00602 {
00603         // Trim quotes if they are on both sides of the string
00604         assertd(pData != NULL);
00605         if ((Len >= 2) && (pData[0] == '\"') && (pData[Len-1] == '\"'))
00606         {
00607                 memmove(pData, pData+1, Len-2+1);
00608                 Len-=2;
00609         }
00610         return *this;
00611 }
00612 
00613 
00614 
00615 /*-------------------------------------------------------------------------------------------------

00616         Assignment/Concatenation

00617 -------------------------------------------------------------------------------------------------*/
00618 
00619 
00620 
00621 //
00622 // Set the string's conents to a copy of <src> with length <len>
00623 //
00624 rcCCString CCString::Copy(const char *src, int len)

00625 {
00626         assertd(len>=0);
00627         assertd(src);
00628         assertd(pData != NULL);
00629 
00630         AllocBuffer(len, false);
00631         Len = len;
00632         memcpy(pData, src, len);
00633         pData[Len] = 0;
00634 
00635         return *this;
00636 }
00637 
00638 
00639 
00640 //
00641 // Concate a number of bytes to the current string
00642 //
00643 rcCCString CCString::Concat(const char *data, int len)

00644 {
00645         assertd(Len>=0);
00646         assertd(len>=0);
00647         assertd(data);
00648         assertd(pData != NULL);
00649 
00650         AllocBuffer(Len+len, true);
00651         memcpy(pData+Len, data, len);
00652         Len+=len;
00653         pData[Len] = 0;
00654 
00655         return *this;
00656 }
00657 
00658 
00659 
00660 
00661 
00662 std::vector<CCString>   CCString::Explode(char c) const

00663 {
00664         CCString                                lcv     = *this;
00665         std::vector<CCString>           uc;
00666 
00667         while (lcv.Length())
00668         {
00669                 int pos = lcv.Find(c);
00670                 if (pos < 0)
00671                 {
00672                         uc.push_back(lcv);
00673                         lcv.Clear();
00674                 } else
00675                 {
00676                         uc.push_back(lcv.Left(pos));
00677                         lcv = lcv.Mid(pos+1);
00678                 }
00679         }
00680 
00681         //uc. -= CCString("");
00682 
00683         return uc;
00684 }
00685 
00686 
00687 /*
00688 
00689 int             CCString::Serialize(pCStream stream)

00690 {

00691         if (stream->GetAccess() == CStream::Access_Read)

00692         {

00693                 int ln;

00694                 stream->Read(&ln, sizeof(ln));

00695                 AllocBuffer(ln, false);

00696                 stream->Read(pData, ln); 

00697                 pData[ln]       = '\0';

00698                 Len                     = ln;

00699         } else

00700         {

00701                 stream->Write(&Len, sizeof(Len));

00702                 stream->Write(pData, Len);

00703         }

00704 
00705         return Len + sizeof(Len);

00706 }

00707 */
00708 

Generated at Thu Feb 1 13:03:12 2001 for Ketsji Game Engine by doxygen1.2.3 written by Dimitri van Heesch, © 1997-2000