00001 /******************************************************************** 00002 Copyright (c) 2001, Lee Patterson & Ant Works Software 00003 http://ssobjects.sourceforge.net 00004 00005 Original source copyright was lost. Modifications by 00006 Lee Patterson. 00007 00008 created : 3/10/2000 00009 filename : cstr.h 00010 author : Lee Patterson (lee@antws.com) 00011 00012 purpose : String class 00013 *********************************************************************/ 00014 00015 #ifndef CSTR_H 00016 #define CSTR_H 00017 00018 #include <assert.h> 00019 #include <stdlib.h> 00020 #include <string.h> 00021 #include "defs.h" 00022 00023 char* strtoupper(char* pszConvert); 00024 char* strtolower(char* pszConvert); 00025 char* ultoa(ulong nValue, char* pszBuffer, uint nRadix=10); 00026 char* ltoa(long nValue, char* pszBuffer, uint nRadix=10); 00027 00028 namespace ssobjects 00029 { 00030 00031 class CStr 00032 { 00033 public: 00034 virtual uint addError(); // Increase the error count and return the new error count. 00035 virtual ~CStr() { empty(); } 00036 00037 public: 00038 // Append new string segment to existing string. If nMaxChars is 0, entire string is appended, otherwise only 00039 // the first nMaxChars of the string is added. To support client not having to check for NULL strings before calling this 00040 // function, it can deal with a NULL value for pszString. If this is the case, the function is a NOOP, and the error count 00041 // is NOT increased. This is not considered an error. If appending a string of a known length, a small performance boost may 00042 // be seen by specifying the known string length in the parameter nKnownStringLength. This value does NOT include the NULL 00043 // terminator. It is valid to call this function with pszString set to itself, or within the existing string. 00044 char* append(const char* pszString, uint nMaxChars = 0, uint nKnownStringLength = 0); 00045 char* append(char nChar); 00046 char* appendCRLF(); 00047 char* appendNumber(int nValue) { return appendNumber((long)nValue); } 00048 char* appendNumber(uint nValue) { return appendNumber((ulong)nValue); } 00049 char* appendNumber(long nValue) { char sz[64]; return append(ltoa(nValue, sz, 10)); } 00050 char* appendNumber(ulong nValue) { char sz[64]; return append(ltoa(nValue, sz, 10)); } 00051 00052 public: 00053 CStr(const char* pszString, uint nMaxChars = 0); 00054 CStr(CStr const& str); 00055 CStr(); 00056 00057 //referancing 00058 operator char* () ; 00059 operator char* () const; 00060 // operator const char* () const; 00061 00062 // Assign to string string 00063 char* format(const char* pszFormat,...); 00064 CStr& operator = (CStr const& s); 00065 CStr& operator = (const char* pszString) { String(pszString); return *this; } 00066 CStr& operator = (int iValue) { String(iValue); return *this; } 00067 CStr& operator = (uint nValue) { String(nValue); return *this; } 00068 00069 // Concatenation of string 00070 char* operator += (const char* pszString) { return append(pszString); } 00071 char* operator << (const char* pszString) { return append(pszString); } 00072 char* operator += (char nChar) { return append(nChar); } 00073 char* operator << (char nChar) { return append(nChar); } 00074 char* operator += (int nValue) { return appendNumber(nValue); } 00075 char* operator << (int nValue) { return appendNumber(nValue); } 00076 char* operator += (uint nValue) { return appendNumber(nValue); } 00077 char* operator << (uint nValue) { return appendNumber(nValue); } 00078 00079 // Comparison of string contents 00080 bool operator == (int nValue) const; 00081 bool operator == (uint nValue) const; 00082 bool operator == (const char* pszString) const; 00083 bool operator != (const char* pszString) const; 00084 00085 00086 // find out information about this object 00087 bool isEmpty() const; 00088 bool isNotEmpty() const; 00089 uint getCharCount(char nChar) const; // Returns the number of times a particular character is found in the string. 00090 00091 00092 //return a referance or set a charactoer at specified index into string 00093 char& charAt(uint nIndex) const; 00094 void charAt(uint nIndex, char nChar); 00095 00096 00097 //Compairs. Returns zero if the strings are identical, -1 if this CStr object is less 00098 //than pszString, or 1 if this CStr object is greater than pszString. 00099 //If either string is NULL or empty, 2 will be returned.*/ 00100 int compare(const char* pszString) const; 00101 int compareNoCase(const char* pszString) const; 00102 00103 00104 // Find first occurence of character or substring in string. 00105 //Returns index into string if found, -1 otherwise. 00106 int find(const char* pszSubString) const; 00107 int find(char nChar) const; 00108 00109 00110 /* Substring extraction, returns a new CStr object with the first nCount of this strings characters in it. If this string 00111 is less that nCount in length, the entire string will be returned.*/ 00112 CStr left(uint nCount) const; 00113 CStr mid(uint nFirst, uint nCount = 0) const; 00114 CStr right(uint nCount) const; 00115 00116 // Remote all spaces from left, right or both sides of a string. 00117 char* trimRight(); 00118 char* trimLeft(); 00119 char* trim(); 00120 00121 // Change case of entire string 00122 char* makeLower(); 00123 char* makeUpper(); 00124 00125 00126 /* Get the length of the string, or if bBuffer is true, the amount of allocated buffer memory. This function could 00127 return 0 when the internal string actually has length. See the String(no parameters) function for more information 00128 about this feature used to avoid unneeded memory allocations.*/ 00129 uint getLength(bool bBuffer = false) const; 00130 uint strlen() {return getLength();} 00131 00132 // Append a character to the end of the string if the string does not already 00133 // end with that character. 00134 // If the string already ends with the character specified by nChar, this 00135 // function will be a NOOP. This function will only succeed on a string that 00136 // already has length. It will not set the first character of an otherwise empty 00137 // string to nChar.*/ 00138 void endWith(char nChar); 00139 00140 00141 // Free the internal buffer and reset internal variables. If bFreeBuffer is true, the internal buffer will be free'd, 00142 // otherwise this function will only reset internal members so the previously allocated memory can be re-used. If the internal 00143 // buffer is kept for future use, this class guards against calls that make use of it. In other words, even if the internal 00144 // pointer m_pszString is not NULL, calls to getLength() or the comparison functions for instance will behave like it is NULL. 00145 char* empty(bool bFreeBuffer = true, bool bResetErrorCount = true); 00146 00147 00148 /* Remove a section from the center of this string. nFirst is the index into this string of the first character to be 00149 removed. nRemoveCount is the number of characters to remove. For example, if this class holds the string "Testing" and 00150 you pass 1 as the first character to remove and 5 as the remove count, the resulting string would be "tg". Starting 00151 with the "e" in "Testing" which is at index 1 in the string, 5 characters, including the "e" were removed. Returns 00152 internal string buffer on success, NULL on failure. On failure, the internal string is not modified. If nRemoveCount 00153 would extend beyond the length of the string, all characters after nFirst (inclusive) will be removed. If nFirst is 00154 0 and nRemoveCount is the string length (or greater), the string will be emptied and NULL returned. This function 00155 never results in a memory allocation, since it shortens the string.*/ 00156 char* removeSection(uint nFirst, uint nRemoveCount = 1); 00157 00158 /* Set a pointer to an externally allocated C style string (allocated with malloc()) into object. This can be done 00159 to replace a string pointer with a previously "stolen" pointer from the StealBuffer() function. This class will 00160 then assume ownership of the string, deleting it as needed. The length of the allocated memory MUST be given to this 00161 class for the function to succeed. The C string essentially becomes a VString object, so the allocated memory size 00162 must be given, and it must be at least 1 byte longer than the string to be valid.*/ 00163 char* replaceBuffer(char* pszString, uint nAllocatedMemorySize, uint nKnownStringLength = 0); 00164 char* replaceBuffer(CStr& strFrom); 00165 char* replaceCharacters(char nFind, char nReplacement); 00166 00167 /* Replace the first occurance of nChar with nReplacement in the string. The default for nReplacement terminates 00168 the string. The return value is the point at which the string was terminated on success, NULL on failure.*/ 00169 char* replaceFirstChar(char nChar, char nReplacement = '\0') { return replaceFirstOrLastChar(nChar, nReplacement, true); } 00170 00171 /* Replace the last occurance of nChar with nReplacement in the string. The default for nReplacement terminates 00172 the string. The return value is the point at which the string was terminated on success, NULL on failure.*/ 00173 char* replaceLastChar(char nChar, char nReplacement = '\0') { return replaceFirstOrLastChar(nChar, nReplacement, false); } 00174 00175 00176 // Return the internal error count. This value is incremented anytime a memory allocation fails, or externally 00177 // by calls to AddError(). 00178 uint getErrorCount() const { return m_nErrorCount; } 00179 00180 /* Return a reference to the granularity size. This is how much memory, during appends, is allocated each time an 00181 append or allocation operation would require more memory than what is currently allocated. Any value, other than 0 is valid 00182 as the granularity setting. The larger the value, the more memory will be allocated each time a new block is required, 00183 but fewer allocations are needed. A smaller number decreases total memory usage, at the expense of more frequent 00184 reallocations. The default value is 64 bytes, and this will be used if set to 0.*/ 00185 uint& getGranularity() const { return (uint&)m_nGranularity; } 00186 00187 00188 00189 00190 /* Steal the C-Style string buffer. Calling code takes ownership of string pointer and must free it when done using the CRT 00191 function free(). On exit, this class is a newly initialized state.*/ 00192 char* stealBuffer(); 00193 00194 /* Get the internal string buffer. It is important to note that a valid buffer pointer might be returned from this 00195 function, even though the CStr class knows the specified length is 0. The reason is that internal buffers can be 00196 reused to avoid unneeded memory allocations. For instance, if you call the Empty() method and tell it not to release 00197 the internal buffer, the internal m_nLength member is set to 0 but the internal string pointer m_pszString is not 00198 touched. Therefore, calling this function would return the internal pointer. This could also be the case where memory 00199 for a string is preallocated with another String() function but not yet populated, or populated but before the 00200 UpdateLength() function is called to set the known string length.*/ 00201 char* String() const { return m_pszString; } 00202 00203 /* Save pszString in class and returns pointer to buffer if a string is held. If nExtraBytes is set, that much 00204 more memory will be allocated in addition to the length of pszString. pszString can be NULL and still have memory 00205 allocated if nExtraBytes is not 0. Using the function this way is a good way to dynamically allocate heap memory 00206 and still have this class free the memory when no longer needed. The allocated memory will be 0 filled. If 00207 extra bytes are allocated, they will be filled with 0's. If this function is used to allocate memory only (pszString 00208 set to NULL and nExtraBytes set to non-0), UpdateLength() should be called as soon as the class contains a valid 00209 string so that future processing using this class is not harmed. 00210 It should be noted that for string that are not likely to change size, this function differs from Append() by not 00211 allocating more memory than is required. This does not affect future appends which can still be done, it merely 00212 means that for strings not likely to change, it uses a more efficient storage scheme. If pszString is not NULL and 00213 nMaxChars is given, only the number of character specified will be copied to the string, although the extra bytes will 00214 still be allocated if given. A very slight performance boost can be realized if the length of pszString is known when 00215 this function is called, and can be specified as the nKnownStringLength parameter. If this function fails to allocate 00216 memory, it will return NULL, however the previous string held by this class will be left intact and safe.*/ 00217 char* String(const char* pszString, uint nExtraBytes = 0, uint nMaxChars = 0, uint nKnownStringLength = 0); 00218 00219 // Set a value into string 00220 char* String(int nValue) { return String((long)nValue); } 00221 char* String(uint nValue) { return String((ulong)nValue); } 00222 char* String(long nValue); 00223 char* String(ulong nValue); 00224 00225 /* This function should be called anytime the length of the string is altered outside of the class. If the exact length 00226 of the string is known (or you want to lie about it), pass a non-0 value for nLength. Passing 0 causes this function to 00227 determine the length of the string. nLength cannot be larger than the real string length, although it can be smaller. Since 00228 this class can be used to store non-string data as a string, which could contain embedded 0 terminators, this class cannot 00229 check the validity of nLength when non-0. Care must be taken here to set the length to the exact length of the data. 00230 This class will verify that nLength is not larger than the internally allocated length.*/ 00231 void updateLength(uint nLength = 0); 00232 00233 protected: 00234 // Copy internal string if pszString is within us. 00235 CStr* duplicateOverlap(const char* pszString, bool& bDuplicateRequired); 00236 00237 // Initialize member variables to default values, or copy from another object. 00238 void init(CStr const* pExisting = NULL); 00239 00240 // Replace the first or last occurance of nChar with nReplacement in the string. 00241 00242 char* replaceFirstOrLastChar(char nChar, char nReplacement, bool bFirst); 00243 00244 // Embedded Member(s). 00245 char* m_pszString; 00246 uint m_nLength; 00247 uint m_nAllocLength; 00248 uint m_nGranularity; 00249 uint m_nErrorCount; 00250 }; 00251 00255 class FmtString : public CStr 00256 { 00257 public: 00258 //construct with a printf style format 00259 FmtString(const char* fmt,...); 00260 }; 00261 00262 }; 00263 00264 00265 #endif 00266 00267