1 // String.h 2 3 #ifndef STRING_H 4 #define STRING_H 5 6 #include <SupportDefs.h> 7 #include <string.h> 8 #include <new> 9 10 11 // string_hash 12 // 13 // from the Dragon Book: a slightly modified hashpjw() 14 static inline 15 uint32 16 string_hash(const char *name) 17 { 18 uint32 h = 0; 19 if (name) { 20 for (; *name; name++) { 21 uint32 g = h & 0xf0000000; 22 if (g) 23 h ^= g >> 24; 24 h = (h << 4) + *name; 25 } 26 } 27 return h; 28 } 29 30 #ifdef __cplusplus 31 32 // String 33 class String { 34 public: 35 inline String(); 36 inline String(const String &string); 37 inline String(const char *string, int32 length = -1); 38 inline ~String(); 39 40 inline bool SetTo(const char *string, int32 maxLength = -1); 41 inline void Unset(); 42 43 inline void Truncate(int32 newLength); 44 45 inline const char *GetString() const; 46 inline int32 GetLength() const { return fLength; } 47 48 inline uint32 GetHashCode() const { return string_hash(GetString()); } 49 50 inline String &operator=(const String &string); 51 inline bool operator==(const String &string) const; 52 inline bool operator!=(const String &string) const { return !(*this == string); } 53 54 private: 55 inline bool _SetTo(const char *string, int32 length); 56 57 private: 58 int32 fLength; 59 char *fString; 60 }; 61 62 // strnlen 63 size_t 64 strnlen(const char *str, size_t maxLen) 65 { 66 if (str) { 67 size_t origMaxLen = maxLen; 68 while (maxLen > 0 && *str != '\0') { 69 maxLen--; 70 str++; 71 } 72 return origMaxLen - maxLen; 73 } 74 return 0; 75 } 76 77 78 /*! 79 \class String 80 \brief A very simple string class. 81 */ 82 83 // constructor 84 String::String() 85 : fLength(0), 86 fString(NULL) 87 { 88 } 89 90 // copy constructor 91 String::String(const String &string) 92 : fLength(0), 93 fString(NULL) 94 { 95 *this = string; 96 } 97 98 // constructor 99 String::String(const char *string, int32 length) 100 : fLength(0), 101 fString(NULL) 102 { 103 SetTo(string, length); 104 } 105 106 // destructor 107 String::~String() 108 { 109 Unset(); 110 } 111 112 // SetTo 113 bool 114 String::SetTo(const char *string, int32 maxLength) 115 { 116 if (string) { 117 if (maxLength > 0) 118 maxLength = strnlen(string, maxLength); 119 else if (maxLength < 0) 120 maxLength = strlen(string); 121 } 122 return _SetTo(string, maxLength); 123 } 124 125 // Unset 126 void 127 String::Unset() 128 { 129 if (fString) { 130 delete[] fString; 131 fString = NULL; 132 } 133 fLength = 0; 134 } 135 136 // Truncate 137 void 138 String::Truncate(int32 newLength) 139 { 140 if (newLength < 0) 141 newLength = 0; 142 if (newLength < fLength) { 143 char *string = fString; 144 int32 len = fLength; 145 fString = NULL; 146 len = 0; 147 if (!_SetTo(string, newLength)) { 148 fString = string; 149 fLength = newLength; 150 fString[fLength] = '\0'; 151 } else 152 delete[] string; 153 } 154 } 155 156 // GetString 157 const char * 158 String::GetString() const 159 { 160 if (fString) 161 return fString; 162 return ""; 163 } 164 165 // = 166 String & 167 String::operator=(const String &string) 168 { 169 if (&string != this) 170 _SetTo(string.fString, string.fLength); 171 return *this; 172 } 173 174 // == 175 bool 176 String::operator==(const String &string) const 177 { 178 return (fLength == string.fLength 179 && (fLength == 0 || !strcmp(fString, string.fString))); 180 } 181 182 // _SetTo 183 bool 184 String::_SetTo(const char *string, int32 length) 185 { 186 bool result = true; 187 Unset(); 188 if (string && length > 0) { 189 fString = new(std::nothrow) char[length + 1]; 190 if (fString) { 191 memcpy(fString, string, length); 192 fString[length] = '\0'; 193 fLength = length; 194 } else 195 result = false; 196 } 197 return result; 198 } 199 200 201 #endif // __cplusplus 202 203 #endif // STRING_H 204