#include <String.h>
Inheritance diagram for String:
Public Member Functions | |
String () | |
String (const char ch) | |
String constructor with a character argument. | |
String (const char *initCstr) | |
String constructor with a C-string argument. | |
String (const String &Str) | |
String copy constructor. | |
SubString | operator() (const size_t start, const size_t len) |
Sub-string operator: this function supports the left hand side (l-value) form for the sub-string operation. | |
size_t | strlen () |
strlen does not include the null at the end of the string | |
size_t | getRefCnt () |
Return the reference count. | |
int | compareTo (const char *Cstr) |
Compare the character string in "this" object with the argument Cstr. | |
String & | resize (const size_t new_size) |
Set the string length of the String to newSize. | |
operator const char * () const | |
This operator allows the assignment of a String to a const char . | |
String & | operator= (const char ch) |
Assign a character to a String. | |
String & | operator= (const char *Cstr) |
Assign a C-string to a String. | |
String & | operator= (const SubString &sub) |
Assign a SubString to a String. | |
String | operator+ (const char *Cstr) |
operator +: String("abcd") + " efgh" | |
String | operator+ (String &s) |
operator +: String("abcd") + String(" efgh") | |
String | operator+ (const char ch) |
operator+ : String + ch | |
String | operator+ (const SubString &sub) |
Append a String and a SubString. | |
String & | operator+= (const char *Cstr) |
Concatenate a C string on to the end of the String object. | |
String & | operator+= (String &s) |
Concatenate two String objects. | |
String & | operator+= (const char ch) |
Append a character to the end of "this" string. | |
bool | operator== (const char *Cstr) |
bool | operator== (String &s) |
bool | operator!= (const char *Cstr) |
bool | operator!= (String &s) |
bool | operator<= (const char *Cstr) |
bool | operator<= (String &s) |
bool | operator>= (const char *Cstr) |
bool | operator>= (String &s) |
bool | operator< (const char *Cstr) |
bool | operator< (String &s) |
bool | operator> (const char *Cstr) |
bool | operator> (String &s) |
Protected Member Functions | |
void | init (const char *initCstr) |
Initialize the underlying data structure for a String container from a C string. | |
size_t | length () |
Return the number of data elements (characters) consumed by the String. | |
void | appendCString (const char *CStr) |
Append a C string at the end of the character string stored in the String object. | |
void | appendString (String &Str) |
Append the characters from "s" onto the end of the characters stored in the String object. | |
void | newEmptyString () |
Make "this" into an empty String. | |
void | newSharedData () |
Allocate a new SharedData object which contains a copy of the old data. | |
int | Cstrcmp (const char *s1, const char *s2) |
Compare two C strings pointed to by const char * pointers. | |
int | compareTo (String &s) |
Compare two strings for equality. | |
Private Attributes | |
friend | SubString |
This class uses reference counts and copy-on-write to improve memory use and, perhaps, performance.
This is the version 3.0 of this class. This class was originally modeled after the Rogue Wave RWCString class (using the documentation available on the Rogue Wave web site).
Why Yet Another String Container
Although I like the Rogue Wave class and the RWCString class in particular, I don't use the Rogue Wave classes in the software I write for Bear Products International. There are several reasons for this. I did not want to pay the Rogue Wave license fees, which are high for a Cave based software developer. Nor did I want to force anyone who licenses my software to also Rogue Wave license fees (sorry guys). I also wanted software that was as transparent as possible. Rogue Wave classes tend to be incompletely documented and it is not always easy to fully understand the way a particular class functions.
Rogue Wave is not the only alternative when it comes to reference counted String containers. The Microsoft Foundation Classes include a string container and some versions of the STL template library implement the STL string container as a reference counted object. Each of these alternatives has some draw back. Microsoft Foundation Class code is not portable outside of Windoz. Also, with the new .NET framework, it seems possible that Microsoft would at some point phase out the Foundation Classes. The reference counted versions of the STL string container that I'm aware of also incur a license fee, although not as steep as Rogue Wave (the Dinkumware STL library is one example of an STL implementation that includes reference counted strings).
Finally, to quote Bjarne Staroustrup
Writing string classes has great educational value...
Chapter 20, The C++ Programming Language, third edition Bjarne Staroustrup
The String class implements a sub-string (string section) operation which results in a SubString object. As a result, the String and SubString classes are closely related.
This class comes with a set of regression tests. I recommend that you run these regression tests with your compiler, on your system. Not all compilers implement C++ in the same way.
Definition at line 99 of file String.h.
|
Definition at line 182 of file String.h. References CharArray.
00182 : CharArray() {} |
|
String constructor with a character argument.
Definition at line 186 of file String.h. References CharArray, and RCArray< char >::value.
|
|
String constructor with a C-string argument.
Definition at line 196 of file String.h. References CharArray, and init().
|
|
String copy constructor.
Definition at line 205 of file String.h. References CharArray, and RCArray< char >::value.
|
|
Append a C string at the end of the character string stored in the String object. The character data stored in a String object should be terminated by a null character (''). The null terminator for the "this" string will be overwritten by the first character of CStr. Reference count and allocation issues should be taken care of by the code that calls this function. Definition at line 67 of file String.C. References length(), and RCArray< char >::value. Referenced by operator+(), and operator+=().
00068 { 00069 if (CStr != 0) { 00070 size_t len = length(); 00071 if (len > 0) { 00072 // if there is a null at the end of the string 00073 // (which there should be) write over it. 00074 if (value->data[len-1] == '\0') { 00075 value->data[len-1] = *CStr++; 00076 } 00077 } 00078 while (*CStr) { 00079 value->data.append( *CStr++ ); 00080 } 00081 value->data.append('\0'); 00082 } 00083 } // appendCString |
|
Append the characters from "s" onto the end of the characters stored in the String object. Note that when String 's' is appended to the String object the null that terminates 's' should be appended as well. Reference count and allocation issues should be taken care of by the code that calls this function. Definition at line 97 of file String.C. References length(), and RCArray< char >::value. Referenced by operator+(), and operator+=().
00098 { 00099 size_t i = 0; 00100 size_t len = s.length(); 00101 size_t thisLen = length(); // length of "this" String 00102 00103 if (thisLen > 0 && len > 0) { 00104 // write over the null character 00105 if (value->data[thisLen-1] == '\0') { 00106 value->data[thisLen-1] = s.value->data[i]; 00107 i++; 00108 } 00109 } // if 00110 while (i < len) { 00111 char ch = s.value->data[i]; 00112 value->data.append( ch ); 00113 i++; 00114 } // while 00115 } // appendString |
|
Compare the character string in "this" object with the argument Cstr.
|
|
Compare two strings for equality.
Definition at line 122 of file String.C. References Cstrcmp(), length(), and RCArray< char >::value. Referenced by operator!=(), operator<(), operator<=(), operator==(), operator>(), and operator>=().
00123 { 00124 if (length() == 0 && s.length() == 0) { 00125 // Both String objects contain no data and so are 00126 // equal 00127 return 0; 00128 } 00129 00130 if (value == s.value) { 00131 // The two String objects point to the same shared data 00132 return 0; 00133 } 00134 00135 const char *pThisCStr = *this; 00136 const char *Cstr = s; 00137 00138 return Cstrcmp( pThisCStr, Cstr ); 00139 } // compareTo |
|
Compare two C strings pointed to by const char * pointers. Return 1 if *pThisCStr is greater than *Cstr, -1 if pThisCstr is less than *Cstr and 0 if *pThisCstr is equal to *Cstr. Definition at line 204 of file String.C. Referenced by compareTo().
00205 { 00206 int rslt; 00207 00208 if (pThisCStr == 0) { 00209 if (Cstr == 0) 00210 rslt = 0; // both this and CStr are null 00211 else { 00212 if (::strlen( Cstr ) == 0) 00213 rslt = 0; // compare to an empty string ("") 00214 else 00215 rslt = -1; // this < Cstr 00216 } 00217 } 00218 else { // pThisCStr != 0 00219 if (Cstr == 0) 00220 rslt = 1; // this > Cstr 00221 else // pThis != 0 && Cstr != 0 00222 rslt = strcmp(pThisCStr, Cstr ); 00223 } 00224 00225 return rslt; 00226 } // Cstrcmp |
|
Return the reference count. This useful primarily for debug and verification. In the perfect world of bug free software the reference count could be entirely hidden. Reimplemented from RCArray< char >. Definition at line 229 of file String.h. References RCArray< char >::getRefCnt(). Referenced by checkRefCnt(), checkRefCntVal(), subStrAssign(), subStrRefCnt(), subStrSection(), test_arrayop(), test_assign(), test_constructors(), test_insert(), test_plus(), test_plus_equal(), and test_substring().
00230 { 00231 return CharArray::getRefCnt(); 00232 } |
|
Initialize the underlying data structure for a String container from a C string.
Definition at line 41 of file String.C. References RCArray< char >::value. Referenced by String().
|
|
Return the number of data elements (characters) consumed by the String. This includes the null character. So length() == strlen() + 1 Definition at line 217 of file String.h. References RCArray< char >::length(). Referenced by appendCString(), appendString(), compareTo(), and resize().
00218 { 00219 return CharArray::length(); 00220 } |
|
Make "this" into an empty String. If "this" is shared, allocate a new SharedData object. If "this" is not shared, set the length to zero. Definition at line 278 of file String.C. References RCArray< char >::value. Referenced by operator=(), and resize().
|
|
Allocate a new SharedData object which contains a copy of the old data. Note that this code relies on the fact that value is a "smart pointer" which will decrement the reference count and deallocate the space if the reference count is zero. Definition at line 306 of file String.h. References RCArray< char >::value. Referenced by operator+(), operator+=(), and resize().
|
|
This operator allows the assignment of a String to a For example, in the code below a is assigned to pStr in the code below:
|
|
Definition at line 155 of file String.h. References compareTo().
00155 { return (compareTo( s ) != 0); } |
|
Definition at line 154 of file String.h. References compareTo().
00154 { return (compareTo( Cstr ) != 0); } |
|
Sub-string operator: this function supports the left hand side (l-value) form for the sub-string operation. For example:
|
|
Append a String and a SubString.
|
|
operator+ : String + ch Append a String and a character. Definition at line 410 of file String.h.
00411 { 00412 char buf[4]; 00413 00414 buf[0] = ch; 00415 buf[1] = '\0'; 00416 00417 String tmp; 00418 00419 tmp = *this + buf; // call String + Cstr 00420 00421 return tmp; 00422 } // operator + |
|
operator +: String("abcd") + String(" efgh")
Definition at line 389 of file String.h. References appendString(), and newSharedData().
00390 { 00391 String tmp; 00392 00393 tmp.newSharedData(); 00394 00395 tmp.appendString( *this ); 00396 tmp.appendString( s ); 00397 00398 return tmp; 00399 } // operator + |
|
operator +: String("abcd") + " efgh" Create a new String object which contains the concatenation of the two operand strings (self and the argument "s"). The reference count for the new String object will be zero. If it is assigned then it will be incremented. Example:
|
|
Append a character to the end of "this" string.
Definition at line 338 of file String.h.
00339 { 00340 char buf[4]; 00341 00342 buf[0] = ch; 00343 buf[1] = '\0'; 00344 00345 *this += buf; // call String += Cstr 00346 return *this; 00347 } // operator += |
|
Concatenate two String objects.
Definition at line 375 of file String.C. References appendString(), newSharedData(), and RCArray< char >::value.
00376 { 00377 if (s.value->data.length() > 0) { 00378 if (value->isShared()) { 00379 newSharedData(); 00380 } 00381 00382 // If there is a null character, delete it so we don't 00383 // append after the null. 00384 size_t len = value->data.length(); 00385 if (len > 0 && value->data[len-1] == '\0') { 00386 value->data.remove(); 00387 } 00388 00389 appendString( s ); 00390 } 00391 return *this; 00392 } // operator += |
|
Concatenate a C string on to the end of the String object. For example:
|
|
Definition at line 161 of file String.h. References compareTo().
00161 { return (compareTo( s ) < 0); } |
|
Definition at line 160 of file String.h. References compareTo().
00160 { return (compareTo( Cstr ) < 0); } |
|
Definition at line 157 of file String.h. References compareTo().
00157 { return (compareTo( s ) <= 0); } |
|
Definition at line 156 of file String.h. References compareTo().
00156 { return (compareTo( Cstr ) <= 0); } |
|
Assign a SubString to a String. For example:
|
|
Assign a C-string to a String. The String(C-string) constructor could be used for this. However, using this default generates code which is more inefficient. The write() function is used here since it properly handles the String shared data. If a null string is assigned to a String, the result will be the same as if an empty String were assigned. For example:
|
|
Assign a character to a String.
Definition at line 293 of file String.C. References newEmptyString(), and RCArray< char >::value.
00294 { 00295 newEmptyString(); 00296 if (ch != '\0') { 00297 value->data.append( ch ); 00298 value->data.append('\0'); 00299 } 00300 return *this; 00301 } // operator= (String = char) |
|
Definition at line 153 of file String.h. References compareTo().
00153 { return (compareTo( s ) == 0); } |
|
Definition at line 152 of file String.h. References compareTo().
00152 { return (compareTo( Cstr ) == 0); } |
|
Definition at line 163 of file String.h. References compareTo().
00163 { return (compareTo( s ) > 0); } |
|
Definition at line 162 of file String.h. References compareTo().
00162 { return (compareTo( Cstr ) > 0); } |
|
Definition at line 159 of file String.h. References compareTo().
00159 { return (compareTo( s ) >= 0); } |
|
Definition at line 158 of file String.h. References compareTo().
00158 { return (compareTo( Cstr ) >= 0); } |
|
Set the string length of the String to newSize. This will be the size returned by String::strlen(). So the actual amount of data allocated will be newSize+1 to account for the null character, assuming that newSize > 0. If newSize == 0, strlen() will be zero and the number of data elements will be zero. The private function length() will return new_size + 1, since the String data is terminated by a null character. If the String is expanded, the String will be padded with spaces. If the reference count of the String object is greater than one, a unique copy will be made when it is resized, since other copies should be unaffected. Definition at line 158 of file String.C. References length(), newEmptyString(), newSharedData(), and RCArray< char >::value. Referenced by test_resize().
00159 { 00160 if (newSize == 0) { 00161 newEmptyString(); 00162 } 00163 else { // newSize > 0 00164 size_t new_len = newSize + 1; 00165 size_t old_len = length(); 00166 00167 if (value->isShared()) { 00168 if (new_len >= old_len) { 00169 // this will copy the data into a new shared data object 00170 newSharedData(); 00171 value->data.set_size( new_len ); 00172 } 00173 else { // new_len < old_len 00174 RCPtr<SharedData> new_value = new SharedData(); 00175 for (size_t i = 0; i < newSize; i++) { 00176 new_value->data.append( value->data[i] ); 00177 } 00178 new_value->data.append('\0'); 00179 // note: smart pointer assignment 00180 value = new_value; 00181 } 00182 } 00183 else { 00184 value->data.set_size( new_len ); 00185 } 00186 00187 for (size_t i = old_len-1; i < new_len-1; i++) { 00188 value->data[i] = ' '; 00189 } 00190 value->data[ new_len-1 ] = '\0'; 00191 } 00192 return *this; 00193 } // resize |
|
strlen does not include the null at the end of the string
Definition at line 433 of file String.h. References RCArray< char >::value. Referenced by SubString::operator=(), subStrAssign(), subStrSection(), test_constructors(), test_resize(), and test_substring().
|
|
|