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();                    
00035     virtual ~CStr() { empty(); }
00036 
00037   public:
00038     
00039     
00040     
00041     
00042     
00043     
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     
00058     operator char* () ;
00059     operator char* () const;
00060 
00061 
00062     
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     
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     
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     
00087     bool isEmpty() const;
00088     bool isNotEmpty() const;
00089     uint getCharCount(char nChar) const;        
00090 
00091 
00092     
00093     char& charAt(uint nIndex) const;
00094     void charAt(uint nIndex, char nChar);
00095 
00096 
00097     
00098     
00099     
00100     int compare(const char* pszString) const;
00101     int compareNoCase(const char* pszString) const;
00102 
00103 
00104     
00105     
00106     int find(const char* pszSubString) const;
00107     int find(char nChar) const;
00108 
00109 
00110     
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     
00117     char* trimRight();
00118     char* trimLeft();
00119     char* trim();
00120 
00121     
00122     char* makeLower();
00123     char* makeUpper();
00124 
00125 
00126     
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     
00133     
00134     
00135     
00136     
00137     
00138     void endWith(char nChar);
00139 
00140 
00141     
00142     
00143     
00144     
00145     char* empty(bool bFreeBuffer = true, bool bResetErrorCount = true);
00146 
00147 
00148     
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     
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     
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     
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     
00177     
00178     uint getErrorCount() const { return m_nErrorCount; }
00179 
00180     
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     
00191        function free(). On exit, this class is a newly initialized state.*/
00192     char* stealBuffer();
00193 
00194     
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     
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     
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     
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     
00235     CStr* duplicateOverlap(const char* pszString, bool& bDuplicateRequired);
00236 
00237     
00238     void init(CStr const* pExisting = NULL);
00239         
00240     
00241         
00242     char* replaceFirstOrLastChar(char nChar, char nReplacement, bool bFirst);
00243 
00244     
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     
00259     FmtString(const char* fmt,...);
00260 };
00261 
00262 };
00263 
00264 
00265 #endif
00266 
00267