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